I would like to rework the Phalcon HTTP stack, particularly the Request
object and its lifecycle.
A while ago I was working on the HTTP authorization issue and turned attention to the fact that by every request of a HTTP header or a variable from $_SERVER
the Request
object scan the $_SERVER
for the value.
Technically, the actual implementation allows to get the value from $_SERVER
and to overwrite it at once bypassing the Request
object. In fact, I don't think it is right. And there are the reasons of this:
- The
Request
object doesn't keep its state, and actually the fact that it isn't static doesn't help much - Any part of the application can quite legally break the request encapsulation just by overwriting
$_SERVER
- We don't use local (static) cache by receiving values from
$_SERVER
,$_REQUEST
and so on, and it has its impact on the performance - Each time, receiving a HTTP header, we convert
HTTP-KEY
toHTTP_KEY
- But by receiving a key from
$_SERVER
we don't do the action described in the previous item - At the moment we don't have methods for receiving raw, untreated keys as well as keys that are ready for the search
- Our ways of work with HTTP headers and other keys from
$_SERVER
can be different by receiving all keys or one key. This means, we receive keys of one type forget all
, but use other keys forget one
, so the user could face difficulties, because the techniques of receiving certain values are not predictable - The user has no possibility to receive a default value if the requested key is absent
On top of everything else I would like to work with the request headers separately. At the moment, I see the Request
object as a composite object which includes such objects as Server
, Headers
, and Files
. Of course, I'd like to substitute mocks for those objects at the stage of testing, or to allow outside developers to create their own extended versions of those objects, which implement the common interface.
If you look at $_SERVER
, $_REQUEST
and $_FILES
attentively, it will be clear for you that these are only collections. Such realization brings about the understanding how the interfaces can be developed, for example, for such classes as Server
, Headers
and Files
. But in fact it causes other questions, too...
For example, if these collections are immutable. On the one hand, it seems that Request
must always be read-only, it reflects its nature. But the current implementation of a HTTP stack, for example, allows to change it in any place of the call stack with ease. Is this right? I'd like to discuss this question.
On the other hand, we'd like to append HTTP headers to a Request
(by using Middlewares), or set the current HTTP method implicitly.
I think, we could do the bigger part of this work in any 3.x
branch, keeping backward compatibility, just by declaring some methods deprecated and deleting them in the 4.x
branch.
In general, I'd like to know the community's opinion as to the questions raised above.