对 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; } }
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: