zanphp源碼解讀 - 請求與響應

前言

也許這是咱們最關係的一個環節了。一個web應用簡單來講無非就是請求和相應了。
獲取你真的該補補 協程 的相關知識了。不過。。
不懂協程懂進程~ 那就 當成進程來看 一個請求一個進 (xie) 程.
懂線程~ 那就 當成 線程來看 一個請求一個線 (xie) 程php

分析 RequestHandler

vendor/zanphp/http-server/src/RequestHandler.phpweb

class RequestHandler
{
    // ...
    
    // 讓 協程來 處理每一個 請求 
    $requestTask = new RequestTask($request, $swooleResponse, $this->context, $this->middleWareManager);
    $coroutine = $requestTask->run();
    $this->task = new Task($coroutine, $this->context);
    $this->task->run();
    clear_ob();
    // ..
}

分析 RequestTask

vendor/zanphp/http-server/src/RequestTask.phpswoole

class RequestTask
{
    public function run()
    {
        yield $this->doRun();
    }
    
    public function doRun()
    {
        // 處理 中間件 邏輯
        $response = (yield $this->middleWareManager->executeFilters());
        if (null !== $response) {
            $this->context->set('response', $response);
            /** @var ResponseTrait $response */
            yield $response->sendBy($this->swooleResponse);
            $this->context->getEvent()->fire($this->context->get('request_end_event_name'));
            return;
        }

        // 處理 中間件 放行後的 邏輯
        $dispatcher = Di::make(Dispatcher::class);
        $response = (yield $dispatcher->dispatch($this->request, $this->context));
        if (null === $response) {
            $code = BaseResponse::HTTP_INTERNAL_SERVER_ERROR;
            $response = new InternalErrorResponse("網絡錯誤($code)", $code);
        }

        yield $this->middleWareManager->executePostFilters($response);

        $this->context->set('response', $response);
        yield $response->sendBy($this->swooleResponse);

        $this->context->getEvent()->fire($this->context->get('request_end_event_name'));
        clear_ob();
    }
}

分析 Dispatcher

vendor/zanphp/http-server/src/Dispatcher.php網絡

<?php

class Dispatcher
{
    public function dispatch(Request $request, Context $context)
    {
        // 看到這些 你應該似曾相識 
        $controllerName = $context->get('controller_name');
        $action = $context->get('action_name');
        $args   = $context->get('action_args');

        if ($args == null) {
            $args = [];
        }

        if ($controllerName === "/" && is_callable($action)) {
            yield $action(...array_values($args));
        } else {
            $controller = $this->getControllerClass($controllerName);
            if(!class_exists($controller)) {
                
                // 這些錯 常見吧
                throw new PageNotFoundException("controller:{$controller} not found");
            }

            $controller = new $controller($request, $context);
            if(!is_callable([$controller, $action])) {
                
                // 這些錯 常見吧
                throw new PageNotFoundException("action:{$action} is not callable in controller:" . get_class($controller));
            }
            yield $controller->$action(...array_values($args));
        }
    }

}
相關文章
相關標籤/搜索