對 Hyperf 做的那些事 2(統一入出口)

作為一個 PHPer 一直思考 PHP 怎麼做高效能(個人基礎比較弱),怎麼微服務,之前真不知道,不是概念而是怎麼落地,談概念有用但是不落地有點扯

Swoole 沒有實際專案用過,swoole 相關框架也沒了解過也不知道,獲取知道了可能對於之前的問題就可能有一些答案了

Hyperf 的出現簡直就是太及時了,文件清晰,框架靈活等等等,簡直不要太好

雖然 Hyperf 已經這麼好了,但是還是希望把它稍微按照自己喜歡的規範改造一下,這裡就把多有對它的改造都定義為自己的開發規範,如果大家覺得有道理可以沿用

感謝 swoole 團隊(韓老師等……),感謝 Hyperf 團隊(黃老師等……)

看完文章是否可以點個贊!!!!

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

開整(2)

操作

統一出口`App\Core\Response`,構造api的返回格式

利用中介軟體,給每一次請求打上qid,記錄每一次的請求日誌

貼程式碼

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; }}