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

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

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

尝试:

在初期我以为是只要在NGINX端开启支持GZIP即可,后面发现NGINX的GZIP开关并不会影响其他客户端发送来的请求数据。

解决:

框架默认只支持json格式,后面通过查看Issues发现有别人踩过类似的(需求)#5488

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  [email protected]
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace Hyperf\HttpMessage\Server;

use Hyperf\HttpMessage\Exception\BadRequestHttpException;
use Hyperf\HttpMessage\Server\Request\Parser;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpMessage\Upload\UploadedFile;
use Hyperf\HttpMessage\Uri\Uri;
use Hyperf\Utils\ApplicationContext;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;

class Request extends \Hyperf\HttpMessage\Base\Request 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) == "\x1f\x8b") {
    
    // 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)


原文链接:https://cloud.tencent.com/developer/article/2368185

猜你喜欢

转载自blog.csdn.net/Glory_Sunshine/article/details/134988940