對 Hyperf 做的那些事 2

xiaoyin199發表於2020-01-02
  1. 作為一個PHPer一直思考PHP怎麼做高效能(個人基礎比較弱),怎麼微服務,之前真不知道,不是概念而是怎麼落地,談概念有用但是不落地有點扯
  2. Swoole沒有實際專案用過,swoole相關框架也沒了解過也不知道,獲取知道了可能對於之前的問題就可能有一些答案了
  3. Hyperf的出現簡直就是太及時了,文件清晰,框架靈活等等等,簡直不要太好
  4. 雖然Hyperf已經這麼好了,但是還是希望把它稍微按著自己喜歡的規範改造一下,這裡就把多有對它的改造都定義為自己的開發規範,如果大家覺得有道理可以沿用
  5. 感謝swoole團隊(韓老師等……),感謝Hyperf團隊(黃老師等……)

工欲善其事,必先利其器,它有個名字HyperfCMS

  1. 操作
    1. 統一出口App\Core\Response,構造api的返回格式
    2. 利用中介軟體,給每一次請求打上qid,記錄每一次的請求日誌
  2. 貼程式碼

    namespace App\Middleware;
    use Psr\Container\ContainerInterface;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Server\MiddlewareInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Server\RequestHandlerInterface;
    use Hyperf\Utils\Context;
    /**
    * RequestMiddleware
    * 接到客戶端請求,通過該中介軟體進行一些調整
    * @package App\Middleware
    * User:YM
    * Date:2019/12/16
    * Time:上午12:13
    */
    class RequestMiddleware implements MiddlewareInterface
    {
    /**
     * @var ContainerInterface
     */
    protected $container;
    
    /**
     * @var ServerRequestInterface
     */
    protected $request;
    
    public function __construct(ContainerInterface $container,ServerRequestInterface $request)
    {
        $this->container = $container;
        $this->request = $request;
    }
    
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 為每一個請求增加一個qid
        $request = Context::override(ServerRequestInterface::class, function (ServerRequestInterface $request) {
            $request = $request->withAddedHeader('qid', $this->getRequestId());
            return $request;
        });
    
        // 利用協程上下文儲存請求開始的時間,用來計算程式執行時間
        Context::set('request_start_time',microtime(true));
    
        $response = $handler->handle($request);
        return $response;
    }
    
    /**
     * getRequestId
     * 唯一請求id
     * User:YM
     * Date:2019/11/18
     * Time:下午7:53
     * @return string
     */
    protected function getRequestId()
    {
        $tmp = $this->request->getServerParams();
        $name = strtoupper(substr(md5(gethostname()), 12, 8));
        $remote = strtoupper(substr(md5($tmp['remote_addr']),12,8));
        $ip = strtoupper(substr(md5(getServerLocalIp()), 14, 4));
        return uniqid(). '-' . $remote. '-'.$ip.'-'. $name;
    }
    }
    namespace App\Core;
    use Hyperf\Di\Annotation\Inject;
    use Hyperf\HttpServer\Contract\RequestInterface;
    use Hyperf\HttpServer\Contract\ResponseInterface;
    use Hyperf\HttpMessage\Cookie\Cookie;
    use App\Constants\StatusCode;
    use Hyperf\Utils\Context;
    use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
    use Hyperf\Utils\Coroutine;
    use App\Core\Facade\Log;
    use Hyperf\Contract\StdoutLoggerInterface;
    /**
    * ReqResponse
    * 請求響應結果
    * @package App\Container
    * User:YM
    * Date:2019/11/15
    * Time:下午5:35
    */
    class Response
    {
    /**
     * @var StdoutLoggerInterface
     */
    protected $logger;
    
    /**
     * @Inject
     * @var RequestInterface
     */
    protected $request;
    
    /**
     * @Inject
     * @var ResponseInterface
     */
    protected $response;
    
    /**
     * success
     * 成功返回請求結果
     * User:YM
     * Date:2019/11/19
     * Time:上午11:04
     * @param array $data
     * @param string|null $msg
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function success(array $data = [], string $msg = null)
    {
        $msg = $msg ?? StatusCode::getMessage(StatusCode::SUCCESS);;
        $data = [
            'qid' => $this->request->getHeaderLine('qid'),
            'code' => StatusCode::SUCCESS,
            'msg'=> $msg,
            'data' => $data
        ];
        $response = $this->response->json($data);
        $executionTime = microtime(true) - Context::get('request_start_time');
        $rbs = strlen($response->getBody()->getContents());
        // 獲取日誌例項,記錄日誌
        $this->logger = Log::get(requestEntry(Coroutine::getBackTrace()));
        $this->logger->info($msg,getLogArguments($executionTime,$rbs));
    
        return $response;
    }
    
    /**
     * error
     * 業務相關錯誤結果返回
     * User:YM
     * Date:2019/11/20
     * Time:上午10:04
     * @param int $code
     * @param string|null $msg
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function error(int $code = StatusCode::ERR_EXCEPTION, string $msg = null)
    {
        $msg = $msg ?? StatusCode::getMessage($code);;
        $data = [
            'qid' => $this->request->getHeaderLine('qid'),
            'code' => $code,
            'msg'=> $msg,
        ];
    
        return $this->response->json($data);
    }
    
    /**
     * json
     * 直接返回資料
     * User:YM
     * Date:2019/12/16
     * Time:下午4:22
     * @param $data
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function json(array $data)
    {
        return $this->response->json($data);
    }
    
    /**
     * xml
     * 返回xml資料
     * User:YM
     * Date:2019/12/16
     * Time:下午4:58
     * @param $data
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function xml(array $data)
    {
        return $this->response->xml($data);
    }
    
    /**
     * redirect
     * 重定向
     * User:YM
     * Date:2019/12/16
     * Time:下午5:00
     * @param string $url
     * @param string $schema
     * @param int $status
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function redirect(string $url,string $schema = 'http', int $status = 302 )
    {
        return $this->response->redirect($url,$status,$schema);
    }
    
    /**
     * download
     * 下載檔案
     * User:YM
     * Date:2019/12/16
     * Time:下午5:04
     * @param string $file
     * @param string $name
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function download(string $file, string $name = '')
    {
        return $this->response->redirect($file,$name);
    }
    
    /**
     * cookie
     * 設定cookie
     * User:YM
     * Date:2019/12/16
     * Time:下午10:17
     * @param string $name
     * @param string $value
     * @param int $expire
     * @param string $path
     * @param string $domain
     * @param bool $secure
     * @param bool $httpOnly
     * @param bool $raw
     * @param null|string $sameSite
     */
    public function cookie(string $name,string $value = '', $expire = 0, string $path = '/', string $domain = '', bool $secure = false, bool $httpOnly = true, bool $raw = false, ?string $sameSite = null)
    {
        // convert expiration time to a Unix timestamp
        if ($expire instanceof \DateTimeInterface) {
            $expire = $expire->format('U');
        } elseif (! is_numeric($expire)) {
            $expire = strtotime($expire);
            if ($expire === false) {
                throw new \RuntimeException('The cookie expiration time is not valid.');
            }
        }
    
        $cookie = new Cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
        $response = $this->response->withCookie($cookie);
        Context::set(PsrResponseInterface::class, $response);
        return;
    }
    }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

小尹你好!
成功細中取,寶貴險中求;細節決定成敗,態度決定一切。

相關文章