Swoole is already the de facto standard for HIGH performance servers in PHP, and you can use swoole to develop a business framework on this blog

Project address: github.com/neatlife/pf…

Welcome star, welcome PR

The core flow chart of framework implementation is as follows (right click to view larger image) :

  1. General-purpose components are implemented in accordance with PSR as far as possible to improve the compatibility of three-party components
  2. event-driven

Global variable adaptation

Swoole is launched from the command line, resident processes run, and Web requests are handled with dependent global variables such as_GET, Instead of filling in a value for each Request, swoole places this per-request variable in the Swoole\Http\Request object

Like swoole’sThe $_SERVER

$server = array_change_key_case($request->server, CASE_UPPER);
foreach ($request->header as $key => $val) {
    $server['HTTP_' . str_replace(The '-'.'_', strtoupper($key))] = $val;
}
$_SERVER = $server;
Copy the code

The correspondence for other environment variables is as follows

$_GET = $request->get;
$_POST = $request->post;
$_COOKIE = $request->cookie;
$_FILES = $request->files;
Copy the code

Symfony Console package

Swoole’s server is launched from the command line, using the Symfony Console component wrapped around it to easily launch Swoole


      
class SwooleServerCommand extends Command
{
    // ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $options = $this->parseOption($input);
        $http = new HttpServer($options['host'], $options['port']);

        $swooleEventHandler = new SwooleEventHandler($this->container);
        foreach (self::$swooleEventList as $eventName) {
            $http->on($eventName, [$swooleEventHandler, 'on' . ucfirst($eventName)]);
        }
        echo "server started at {$options['host']}:{$options['port']}..." . PHP_EOL;
        $http->start();
    }

    // ...
}
Copy the code

Symfony EventDispatcher distributes swoole events

Swoole’s HTTP events are triggered by Swoole’s callback function. Event dispatchers are used here to separate the framework’s code from Swoole as much as possible, achieving the goal of loose coupling

The event dispatcher is used here to handle swoole’s start and request events

Create an event dispatcher object

$this->eventDispatcher = new EventDispatcher();
Copy the code

Distribute start and Request events

class SwooleEventHandler
{
    public function onStart(a)
    {
        Application::getInstance()->getEventDispatcher()->dispatch(Event::START, new GenericEvent());
    }

    public function onRequest(Request $request, Response $response)
    {
        $server = array_change_key_case($request->server, CASE_UPPER);
        foreach ($request->header as $key => $val) {
            $server['HTTP_' . str_replace(The '-'.'_', strtoupper($key))] = $val;
        }
        $_SERVER = $server;

        Application::getInstance()->getEventDispatcher()->dispatch(Event::REQUEST, newGenericEvent($response)); }}Copy the code

Swoole complete event list reference: wiki.swoole.com/wiki/page/4…

Symfony Dependency Injection provides an object container

Symfony containers are used to share all application objects to avoid repeated object creation, and objects in the container can be easily accessed anywhere in the application

Create a container

new ContainerBuilder();
Copy the code

Set the object

$this->container->set(Application::class, $this);
Copy the code

Access to the object

$this->container->get(Application::class);
Copy the code

Middleware handles HTTP requests

Middleware is typically designed to make nested calls, in which case they need to be implemented recursively. The core code is as follows

protected function callMiddleware($request, $response, $index = 0)
{
    if (!isset($this->middleware[$index])) {
        return $response;
    }

    $middleware = new $this->middleware[$index];
    return $middleware($request, $response, function ($request, $response) use ($index) {
        $this->callMiddleware($request, $response, $index + 1);
    });
}
Copy the code

composer.json

The complete composer. Json dependencies are as follows

"Require ": {"symfony/event-dispatcher": "^3.4", "symfony/event-dispatcher": "^3.4", "symfony/dependency-injection": "^ 3.4 symfony/HTTP -", "foundation" : "^ 3.4}", "the require - dev" : {" phpunit/phpunit ":" ^ 6.0 "},Copy the code

A couple of points to note

Symfony’s Request object does not implement the PSR ServerRequestInterface. If you want to comply with the PSR Request, you can consider other Request components, such as the Zend framework’s Request

The resources

  1. www.php-fig.org/psr/
  2. Wiki.swoole.com/wiki/page/3…

Continuously updated…