Design Discussion: Yii2 abstract $_SERVER variables for each request into a \yii\web\Server class

This design discussion is proposing a new class, yii\web\Server, to abstract $_SERVER variables referenced in the Yii2 Framework.

With the release of PHP7 and the new Pthreads package, running a threaded HTTP Server from the PHP CLI is now a viable thing to do (as opposed to running a webserver and running PHP as a FastCGI script). The Yii2 Framework directly references $_SERVER variables in many places, which are global variables and cannot be changed on each request. In order to support multiple requests within the same process, these variables would need to be moved to an abstracted class.

The flow for a pure PHP HTTP Server run from the command line would be:

  1. Main PHP CLI thread accepts socket connection, parses HTTP Request

  2. Create a new instance of \yii\web\Server containing appropriate $_SERVER Variables




$server = new \yii\web\Server([

    'host' => 'example.com',

    'requestMethod' => 'GET',

    'requestUri' => '/',

    ...

]);



  1. Create a web application config with:



...

    'components' => [

        'request' => [

             'class' => 'common\components\redis\queue\Endpoint',

             'server' => $server, // the initialized \yii\web\Server object

         ]    

    ]

...



If no $this->server variable is set in the \yii\web\Request, then \yii\web\Request would default to using values from the $_SERVER variable. This would maintain compatibility for FastCGI scripts. \yii\web\Request would need to define a function:




private $_server;


function getServer(){

    if (!$this->_server){

        $this->_server = new Server([

            'host' => $_SERVER['HTTP_HOST'],

            'requestMethod' => $_SERVER['REQUEST_METHOD'],

            'requestUri' => $_SERVER['REQUEST_URI'],

            ...

        ]);

    }

}



Adding this feature would allow for running Yii2 Web Applications from existing HTTP Parsers such as:

React PHP HTTP Server: https://github.com/reactphp/http

HTTP Parser: https://github.com/chobie/php-httpparser

Yii2 could also add a helper class, something along the lines of yii\helpers\Http::parseRequest($rawRequest) to turn a raw HTTP Request into a yii\web\Server object.

In order to implement this, all references to $_SERVER in the Yii2 framework would have to be replaced with references to Yii::$app()->request->server, and all $_SERVER indicies that Yii2 references would have to be supported (full list at http://php.net/manual/en/reserved.variables.server.php).

It’s my opinion that supporting a long-running HTTP Server from the CLI is important for PHP and thus important for Yii. With development headed towards microservices, it is increasingly common to see small long-running HTTP Servers that store some sort of state in memory from one request to the next. This is not currently possible with a FastCGI approach.

I’m willing to take a stab at the implementation, but since it is such a major design change, I’d like feedback first.

Discussion moved to GitHub https://github.com/yiisoft/yii2/issues/10824

1 Like