使用Hyperf中遇到的问题及解决方法【一】

2023-12-06 20:18:07 浏览数 (1)

Hyperf 是一个高性能、高灵活性的渐进式 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于PHP-FPM的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于PSR 标准实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是可替换可复用的。(简短介绍来源于:https://hyperf.wiki/3.1/#/)

问题一:需要接收其他客户端发送的二进制数据(GZIP压缩的数据)

在初期我以为是只要在NGINX端开启支持GZIP即可,后面发现NGINX的GZIP开关并不会影响其他客户端发送来的请求数据。框架默认只支持json格式,后面通过查看Issues发现有别人踩过类似的(需求)#5488

代码语言:javascript复制
<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace HyperfHttpMessageServer;

use HyperfHttpMessageExceptionBadRequestHttpException;
use HyperfHttpMessageServerRequestParser;
use HyperfHttpMessageStreamSwooleStream;
use HyperfHttpMessageUploadUploadedFile;
use HyperfHttpMessageUriUri;
use HyperfUtilsApplicationContext;
use PsrHttpMessageRequestInterface;
use PsrHttpMessageServerRequestInterface;
use PsrHttpMessageUploadedFileInterface;

class Request extends HyperfHttpMessageBaseRequest implements ServerRequestInterface
{
    // ...省略多余代码 只展示关键改动代码
    
    protected static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null)
    {
        if (! $request) {
            return $data;
        }

        $rawContentType = $request->getHeaderLine('content-type');
        if (($pos = strpos($rawContentType, ';')) !== false) {
            // e.g. text/html; charset=UTF-8
            $contentType = strtolower(substr($rawContentType, 0, $pos));
        } else {
            $contentType = strtolower($rawContentType);
        }

        try {
            $parser = static::getParser();
            // 此处新增对Gzip的请求头处理
            $content = (string) $request->getBody();
            if (strpos($request->getHeaderLine('content-encoding'), 'gzip') !== false && substr($content, 0, 2) == "x1fx8b") {// str_contains($request->getHeaderLine('content-encoding'), 'gzip')
                // 如果有gzip请求头,对请求content进行gz解压(为求稳 同时判断前面的字节是否为二进制)
                $content = gzdecode("$content");
            }
            if ($parser->has($contentType) && $content) {
                $data = $parser->parse($content, $contentType);
            }
        } catch (InvalidArgumentException $exception) {
            throw new BadRequestHttpException($exception->getMessage());
        }

        return $data;
    }

}

以上代码块是我基于自己开发环境中实际改动调整的地方;由于生产环境是2.2版本,遂自行进行一定改动。

总结

通过本次解决问题,复习及学习了几个PHP函数

strpos()(PHP 4, PHP 5, PHP 7, PHP 8)

substr()(PHP 4, PHP 5, PHP 7, PHP 8)

str_contains()(PHP 8)

gzuncompress()(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

gzdecode()(PHP 5 >= 5.4.0, PHP 7, PHP 8)

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞