Request-Interop is based on research including the following projects, which model their request objects on the PHP superglobals:
- aura/web (aura)
- Cake 2 CakeRequest (cake2)
- Code Igniter 3 CI_Input (ci3)
- flightphp/core (flight)
- horde/controller (horde)
- joomla/input (joomla)
- Klein (klein)
- MediaWiki (mediawiki)
- nette/http (nette)
- Phalcon HTTP Request (phalcon)
- Slim 2 (slim2)
- symfony/http-foundation (symfony)
- tempestphp/tempest-framework (tempest)
- YAF (yaf)
- yiisoft/yii2-dev (yii2)
- Zend Framework 1 (zf1)
The following projects were considered but eventually excluded, because they attempt to model their request objects on HTTP messages instead of on the PHP superglobals:
- Lithium lithium\action\Request
- PSR-7 Psr\Http\Message\ServerRequestInterface
- Zend Framework 2 Zend\Http\PhpEnvironment\Request
(The last two are remarkably similar.)
See also https://docs.google.com/spreadsheets/d/e/2PACX-1vQzJP00bOAMYGSVQ8QIIJkXVdAg-OMEfkgna7-b2IsuoWN8x_TazxEYn-yVDF2XQIqnzmHqdDO3KEKx/pubhtml for an earlier version of this research.
The projects offer varying levels of nominal mutability. Note that "readonly" here means the project does not allow public mutability; formal readonly might not be in place, thus allowing mutability within protected or private scopes, but not from outside the object.
| Readonly | Mutable | |
|---|---|---|
| aura | x | |
| cake2 | x | |
| ci3 | x | |
| flight | x | |
| horde | x | |
| joomla | x | |
| klein | x | |
| mediawiki | x | |
| nette | x | |
| phalcon | x | |
| symfony | x | |
| tempest | x | |
| yaf | x | |
| yii2 | x | |
| zf1 | x |
None of the researched projects advertise immutability.
The projects provide access to the most or all of the following superglobals via a property or method.
| Access | Type | |
|---|---|---|
| aura | $query |
Values class |
| cake2 | $query |
array |
| ci3 | get() |
array |
| flight | $query |
Collection class |
| horde | getGetVars() |
array |
| joomla | $get |
Input class |
| klein | paramsGet() |
DataCollection class |
| mediawiki | getQueryValuesOnly() |
array |
| nette | getQuery() |
array |
| phalcon | getQuery() |
array |
| slim2 | get() |
array |
| symfony | $query |
InputBag class |
| tempest | $query |
array |
| yaf | getQuery() |
array |
| yii2 | getQueryParams() |
array |
| zf1 | getQuery() |
array |
The naming for this superglobal is less consistent than for the other superglobals; the researchers presume it is because $_POST is a representation of the HTTP request body, which may be present in requests other than POST.
| Access | Type | post | data | params | body | |
|---|---|---|---|---|---|---|
| aura | $post |
Values class | x | |||
| cake2 | $data |
array |
x | |||
| ci3 | post() |
array |
x | |||
| flight | $data |
Collection class | x | |||
| horde | getPostVars() |
array |
x | |||
| joomla | $post |
Input class | x | x | ||
| klein | paramsPost() |
PostCollection class | x | |||
| mediawiki | getPostValues() |
array |
x | |||
| nette | getPost() |
array |
x | |||
| phalcon | getPost() |
array |
x | |||
| slim2 | post() |
array |
x | |||
| symfony | $request |
InputBag class | ||||
| tempest | $body |
array |
x | |||
| yaf | getPost() |
array |
x | |||
| yii2 | getBodyParams() |
`array | object` | x | ||
| zf1 | getPost() |
array |
x |
| Access | Type | |
|---|---|---|
| aura | $cookies |
Values class |
| cake2 | - | - |
| ci3 | cookie() |
array |
| flight | $cookies |
Collection class |
| horde | getCookieVars() |
array |
| joomla | $cookie |
Cookie class |
| klein | cookies() |
CookieCollection class |
| mediawiki | getCookieArray() |
array |
| nette | $cookies |
array |
| phalcon | - | - |
| slim2 | cookies() |
Cookies class |
| symfony | $cookies |
InputBag class |
| tempest | $cookies |
array |
| yaf | getCookie() |
array |
| yii2 | getCookies() |
CookieCollection class |
| zf1 | getCookie() |
array |
| Access | Type | |
|---|---|---|
| aura | $server |
Values class |
| cake2 | env() |
array |
| ci3 | server() |
array |
| flight | - | - |
| horde | getServerVars() |
array |
| joomla | $server |
Input class |
| klein | server() |
ServerCollection class |
| mediawiki | - | - |
| nette | - | - |
| phalcon | getServer() |
array |
| slim2 | - | - |
| symfony | $server |
ServerBag class |
| tempest | - | - |
| yaf | getServer() |
array |
| yii2 | - | - |
| zf1 | getServer() |
array |
Note that some projects retain only the native $_FILES structure, while others provide a restructured variation.
| Project | Access | Type | Structure |
|---|---|---|---|
| aura | $files |
Files class | Restructured |
| cake2 | $data |
array |
Restructured |
| ci3 | (1) | CI_Upload class | Restructured |
| flight | getUploadedFiles |
UploadedFile array | Restructured |
| horde | getFileVars() |
array |
Native |
| joomla | $files |
Files class | Native |
| klein | files() |
UploadedFileCollection | Native |
| mediawiki | getUpload() |
WebRequestUpload | Restructured |
| nette | getFiles() |
FileUpload array | Restructured |
| phalcon | getUploadedFiles() |
File array | Restructured |
| slim2 | - | - | - |
| symfony | $files |
FileBag class | Restructured |
| tempest | files() |
Upload array | Restructured |
| yaf | getFiles() |
array |
Native |
| yii2 | - | - | - |
| zf1 | - | - | - |
(1) CI_Upload is unusual, in that it is more of a file-processing object than a file representation object.
Most projects provide access to the incoming request headers, typically extracted from $_SERVER values.
| Access | Type | |
|---|---|---|
| aura | $headers |
Headers class |
| cake2 | header() |
array |
| ci3 | request_headers() |
array |
| flight | getHeaders() |
array |
| horde | getHeaders() |
array |
| joomla | - | - |
| klein | headers() |
HeadersCollection class |
| mediawiki | getAllHeaders() |
array |
| nette | getHeaders() |
array |
| phalcon | getHeaders() |
array |
| slim2 | headers() |
Headers class |
| symfony | $headers |
HeaderBag class |
| tempest | $headers |
RequestHeaders class |
| yaf | - | - |
| yii2 | getHeaders() |
HeaderCollection class |
| zf1 | getHeader() (1) |
string |
(1) ZF1 only allows retrieval of one header at a time.
The projects make the HTTP method of the incoming request accessible via a property or method.
| Access | Type | |
|---|---|---|
| aura | $method |
Method class |
| cake2 | method() |
string |
| ci3 | method() |
string |
| flight | $method |
string |
| horde | getMethod() |
string |
| joomla | getMethod() |
string |
| klein | method() |
string |
| mediawiki | getMethod() |
string |
| nette | getMethod() |
string |
| phalcon | getMethod() |
string |
| slim2 | getMethod() |
string |
| symfony | getMethod() |
string |
| tempest | getMethod() |
Method enum |
| yaf | getMethod() |
string |
| yii2 | getMethod() |
string |
| zf1 | getMethod() |
string |
Most projects provide a representation of the incoming request URI or URL, accessible via a property or method:
| URI | URL | Access | Type | |
|---|---|---|---|---|
| aura | x | $url |
Url class | |
| cake2 | x | $url |
string |
|
| ci3 | x | $uri |
CI_URI class | |
| flight | x | $url |
string |
|
| horde | - | - | - | - |
| joomla | - | - | - | - |
| klein | x | uri() |
string |
|
| mediawiki | x | getRequestURL() |
string |
|
| nette | x | getUrl() |
UrlScript class | |
| phalcon | x | getURI() |
string |
|
| slim2 | x | getResourceUri() |
string |
|
| symfony | x | getUri() |
string |
|
| tempest | x | $uri |
string |
|
| yaf | x | getRequestUri() |
string |
|
| yii2 | x | getUrl() |
string |
|
| zf1 | x | getRequestUri() |
string |
Most projects provide access to php://input via a property or method, though the naming is inconsistent.
| Access | Type | raw | body | content | input | |
|---|---|---|---|---|---|---|
| aura | - | - | ||||
| cake2 | - | - | x | |||
| ci3 | $raw_input_stream |
string |
x | |||
| flight | getBody() |
string |
x | |||
| horde | - | - | ||||
| joomla | - | - | ||||
| klein | body() |
string |
x | |||
| mediawiki | getRawInput() |
string |
x | x | ||
| nette | getRawBody() |
`string | null` | x | x | |
| phalcon | getRawBody() |
string |
x | x | ||
| slim2 | getBody() |
string |
x | |||
| symfony | getContent() |
`string | resource` | x | ||
| tempest | $raw |
string |
x | |||
| yaf | getRaw() |
mixed |
x | |||
| yii2 | getRawBody() |
string |
x | x | ||
| zf1 | getRawBody() |
string |
x | x |
The projects offer varying levels of support for creating request objects from
the PHP superglobals. Some projects provide factory methods or constructors that
accept superglobal arrays, while others require only instantiation via the new
keyword.
- "Factory Class" indicates a separate factory class for creating the request object.
- "Factory Method" indicates a creation method on the request object itself.
| Factory Class | Factory Method | new |
|
|---|---|---|---|
| aura | x | ||
| cake2 | x | ||
| ci3 | x | ||
| flight | x | ||
| horde | x | ||
| joomla | x | ||
| klein | x | ||
| mediawiki | x | ||
| nette | x | ||
| phalcon | x | ||
| slim2 | x | ||
| symfony | x | ||
| tempest | x | ||
| yaf | x | ||
| yii2 | x | ||
| zf1 | x |
Signatures are as follows:
| Creation Signature | |
|---|---|
| aura | public function WebFactory::newRequestGlobals(): Request\Globals |
| cake2 | public function __construct(?string $url = null, bool $parseEnvironment = true) |
| ci3 | public function __construct() |
| flight | public function __construct(array $config = []) |
| horde | - |
| joomla | public function __construct(?array $source = $_REQUEST, array $options = []) |
| klein | public static function createFromGlobals(): Request |
| mediawiki | public function __construct() |
| nette | public function RequestFactory::fromGlobals(): Request |
| phalcon | - |
| slim2 | public function __construct(\Slim\Environment $env) |
| symfony | public static function createFromGlobals(): static |
| tempest | public function RequestFactory::make(): PsrRequest |
| yaf | public function __construct(?string $uri = null, ?string $base_uri = null) |
| yii2 | - |
| zf1 | public function __construct(string|Zend_Uri|null $uri = null) |
Note that some of the projects do not have a constructor for the request object.
In no case do any of the projects fail to create a request using its default arguments, typically the PHP superglobals. That is, the request object is always created, even if the project needs to set its own values for missing or invalid values.
Coupling of request objects to the superglobal variables is varied across the researched projects.
-
"Injected" indicates the superglobals (or the request property values themselves) are passed as arguments into the creation mechanism from the outside. The request object is decoupled from the superglobals; changes to one do not affect the other.
-
"Located" indicates the creation mechanism copies the superglobals itself from the inside. The request object is decoupled from the superglobals; changes to one do not affect the other.
-
"Coupled" indicates the request object uses the superglobals themselves; changes to the superglobals are reflected inside the requested object.
| Injected | Located | Coupled | |
|---|---|---|---|
| aura | x | ||
| cake2 | x | ||
| ci3 | x | ||
| flight | x | ||
| horde | x | ||
| joomla | x | ||
| klein | x | ||
| mediawiki | x | ||
| nette | x | ||
| phalcon | x | ||
| slim2 | x | ||
| symfony | x | ||
| tempest | x | ||
| yaf | x | ||
| yii2 | x | ||
| zf1 | x |