Skip to content

Convert HttpRequest/HttpResponse from static to instance-based #454

Closed

Description

@armanist

Summary

HttpRequest and HttpResponse currently store all request/response state in ~15+ static properties spread across ~10 traits. This makes it impossible to run two application executions in the same process without state leaking between them, and complicates test isolation.

This ticket converts HttpRequest/HttpResponse (and their traits) from static state to instance-based state, with instances managed by the DI container.

Parent Issue

Subtask of #373 (Refactor App Bootstrapping & DI Ownership Model).

Problem

Current static properties in the HTTP layer:

HttpRequest (src/Http/Request/HttpRequest.php):

  • $__method, $server, $initialized

Request traits:

  • Url: $__protocol, $__host, $__port, $__uri
  • Query: $__query
  • Header: $__headers
  • Body: $__request
  • File: $__files
  • Route: $route
  • Params: $__contentType

HttpResponse (src/Http/Response/HttpResponse.php):

  • $xmlRoot, $callbackFunction, $initialized

Response traits:

  • Body: $__response, $formatters
  • Header: $__headers
  • Status: $__statusCode, $texts

All of these are private static or protected static — they survive across executions in the same process, causing state leakage.

Proposed Changes

  1. Convert all static properties in HttpRequest, HttpResponse, and their traits to instance properties
  2. Convert static methods that access these properties to instance methods
  3. Register Request and Response instances in DI during the boot pipeline
  4. Update all consumers (helpers, adapters, router, middleware, LangFactory, etc.) to resolve Request/Response from DI instead of calling static methods
  5. Ensure Di::autowire() continues to inject Request/Response into controller methods

Affected Areas

Core HTTP classes

  • src/Http/Request/HttpRequest.php
  • src/Http/Response/HttpResponse.php
  • src/Http/Traits/Request/Url.php
  • src/Http/Traits/Request/Query.php
  • src/Http/Traits/Request/Header.php
  • src/Http/Traits/Request/Body.php
  • src/Http/Traits/Request/File.php
  • src/Http/Traits/Request/Route.php
  • src/Http/Traits/Request/Params.php
  • src/Http/Traits/Request/RawInput.php
  • src/Http/Traits/Request/Internal.php
  • src/Http/Traits/Response/Body.php
  • src/Http/Traits/Response/Header.php
  • src/Http/Traits/Response/Status.php

Consumers that call Request/Response statically

  • src/Http/Helpers/http.php
  • src/Router/RouteDispatcher.php
  • src/Router/RouteFinder.php
  • src/Router/Helpers/router.php
  • src/Lang/Factories/LangFactory.php (getLangFromQuery, getLangFromUrlSegment)
  • src/Middleware/MiddlewareManager.php
  • src/App/Adapters/WebAppAdapter.php
  • src/Csrf/Csrf.php
  • src/View/Helpers/view.php
  • Tests across Unit/Http/, Unit/Router/, Unit/App/

Acceptance Criteria

  • No private static or protected static properties storing request/response state
  • Request and Response are DI-managed instances
  • All existing tests pass
  • Controller autowiring still injects Request/Response correctly
  • Helper functions (redirect(), redirectWith(), old(), get_referrer(), etc.) work unchanged

Context

This is a prerequisite for making AppContext the true execution state holder (#373) and for the Di facade/DiContainer split. Once Request/Response are instance-based and DI-managed, each application execution can have its own isolated HTTP state.

Activity

  1. added this to the 3.0.0 milestone on Apr 9, 2026
  2. self-assigned this
    on Apr 11, 2026
  3. added 3 commits that reference this issue on Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions