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) :
- General-purpose components are implemented in accordance with PSR as far as possible to improve the compatibility of three-party components
- 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
- www.php-fig.org/psr/
- Wiki.swoole.com/wiki/page/3…
Continuously updated…