hypef 五、请求及响应

文档地址

Hyperf

https://hyperf.wiki/2.0/#/zh-cn/response

一、请求

1.1 安装

composer require hyperf/http-message

 框架自带不用手动安装。

1.2 请求对象

      在 onRequest 生命周期内可获得Hyperf\HttpServer\Request对象。

  可以通过以来注入和路由对应参数获取。

declare(strict_types=1);

namespace App\Controller;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\AutoController;

/**
 * @AutoController()
 */
class IndexController
{
    public function info(RequestInterface $request, int $id)
    {
        $r_id = $request->route('id');
        // 存在则返回,不存在则返回默认值 0
        $r_id = $request->route('id', 0);
    }
    public function info2()
    {
        $r_id = $this->request->route('id');
        // 存在则返回,不存在则返回默认值 0
        $r_id = $this->request->route('id', 0);
    }
}

 1.3 获取请求内容

#获取路径
$uri = $request->path();

#验证路由匹配
if ($request->is('user/*')) {
    // ...
}

#获取url 无参数
$url = $request->url();

#获取url 带参数
$url = $request->fullUrl();

#获取请求方法
$method = $request->getMethod();

if ($request->isMethod('post')) {
    // ...
}

#获取所有输入】
$all = $request->all();

#获取指定输入
$name = $request->input('name');
$name = $request->input('name', 'Hyperf');
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');

#从查询字符串中取出
$name = $request->query();
$name = $request->query('name');//默认null
$name = $request->query('name', 'Hyperf');

#获取josn信息
$name = $request->input('user.name');
$name = $request->input('user.name', 'Hyperf');
$name = $request->all();//以数据形式返回

#判断是否存在
if ($request->has('name')) {
    // ...
}
#同时判断多个值
if ($request->has(['name', 'email'])) {
    // ...
}

 1.4 PRS-7请求及方法

hyperf/http-message组件实现PSR-7标准。

注入时声明为 PSR-7 标准的 Psr\Http\Message\ServerRequestInterface 接口,则框架会自动转换为等同于 Hyperf\HttpServer\Contract\RequestInterfaceHyperf\HttpServer\Request 对象。

建议使用 Hyperf\HttpServer\Contract\RequestInterface 来注入,这样可获得 IDE 对专属方法的自动完成提醒支持。

1.5 cookies

#获取所有cookies
$cookies = $request->getCookieParams();

#获取单个
$name = $request->cookie('name');
$name = $request->cookie('name', 'Hyperf');

1.6 文件

SplFileInfo文档:PHP: SplFileInfo - Manual

Hyperf\HttpMessage\Upload\UploadedFile::file()从请求中获取上传的文件对象,返回Hyperf\HttpMessage\Upload\UploadedFile 类的实例,UploadedFile类继承SplFileInfo。

Hyperf\HttpServer\Reques继承Hyperf\HttpServer\Contract\RequestInterface,RequestInterface继承sr\Http\Message\ServerRequestInterface,RequestInterface其中有定义file(),Reques实现file。

 #Hyperf\HttpServer\Request 
    /**
     * Retrieve a file from the request.
     *
     * @param null|mixed $default
     * @return null|UploadedFile|UploadedFile[]
     */
public function file(string $key, $default = null)
    {
        return Arr::get($this->getUploadedFiles(), $key, $default);
    }
public function getUploadedFiles()
    {
        return $this->call(__FUNCTION__, func_get_args());
    } 
protected function call($name, $arguments)
    {
        $request = $this->getRequest();
        if (! method_exists($request, $name)) {
            throw new \RuntimeException('Method not exist.');
        }
        return $request->{$name}(...$arguments);
    }



#Hyperf\HttpMessage\Upload\UploadedFile
class UploadedFile extends \SplFileInfo implements UploadedFileInterface
{
}
#获取上传文件
$file = $request->file('photo');

#检查文件是否存在
if ($request->hasFile('photo')) {
    // ...
}

#验证上传
if ($request->file('photo')->isValid()) {
    // ...
}

#获取文件路径
$path = $request->file('photo')->getPath();

#获取扩张名
$extension = $request->file('photo')->getExtension();

#存储上传文件
$file = $request->file('photo');
$file->moveTo('/foo/bar.jpg');

// 通过 isMoved(): bool 方法判断方法是否已移动
if ($file->isMoved()) {
    // ...
}

 

二、响应

2.1 返回数据

Hyperf\HttpServer\Response中定义犯法并使用对应类处理。

public function write(string $data): bool
    {
        $response = $this->getResponse();
        if ($response instanceof Chunkable) {
            return $response->write($data);
        }

        return false;
    }
public function json($data): PsrResponseInterface
    {
        $data = $this->toJson($data);
        return $this->getResponse()
            ->withAddedHeader('content-type', 'application/json; charset=utf-8')
            ->withBody(new SwooleStream($data));
    }
 public function xml($data, string $root = 'root'): PsrResponseInterface
    {
        $data = $this->toXml($data, null, $root);
        return $this->getResponse()
            ->withAddedHeader('content-type', 'application/xml; charset=utf-8')
            ->withBody(new SwooleStream($data));
    }
public function raw($data): PsrResponseInterface
    {
        return $this->getResponse()
            ->withAddedHeader('content-type', 'text/plain; charset=utf-8')
            ->withBody(new SwooleStream((string) $data));
    }
public function redirect(
        string $toUrl,
        int $status = 302,
        string $schema = 'http'
    ): PsrResponseInterface {
        $toUrl = value(function () use ($toUrl, $schema) {
            if (! ApplicationContext::hasContainer() || Str::startsWith($toUrl, ['http://', 'https://'])) {
                return $toUrl;
            }
            /** @var Contract\RequestInterface $request */
            $request = ApplicationContext::getContainer()->get(Contract\RequestInterface::class);
            $uri = $request->getUri();
            $host = $uri->getAuthority();
            // Build the url by $schema and host.
            return $schema . '://' . $host . (Str::startsWith($toUrl, '/') ? $toUrl : '/' . $toUrl);
        });
        return $this->getResponse()->withStatus($status)->withAddedHeader('Location', $toUrl);
    }
protected function toJson($data): string
    {
        try {
            $result = Json::encode($data);
        } catch (\Throwable $exception) {
            throw new EncodingException($exception->getMessage(), $exception->getCode());
        }

        return $result;
    }
    protected function toXml($data, $parentNode = null, $root = 'root'): string
    {
        return Xml::toXml($data, $parentNode, $root);
    }

    
    protected function getResponse()
    {
        if ($this->response instanceof PsrResponseInterface) {
            return $this->response;
        }

        return Context::get(PsrResponseInterface::class);
    }

 这块设计几乎是整个Response类,显示可以写入数据和获取请求数据。

#返回json
return $response->json($data);

#返回xml
return $response->xml($data);

#返回raw
return $response->raw('Hello Hyperf.');

#重定向
return $response->redirect('/anotherUrl');

#cookie设置
$cookie = new Cookie('key', 'value');
return $response->withCookie($cookie)->withContent('Hello Hyperf.');

#文件下载
return $response->download(BASE_PATH . '/public/file.csv', 'filename.csv');

三、其他相关

两个教程里涉及 immutable 机制,是php7优化内容。

3.1 immutable机制

文档https://blog.blackfire.io/php-7-performance-improvements-immutable-arrays.html

 immutable机制为php7优化内容,使为修改或复制过的变量仅创建一次,对框架中规模比较大的变量减少创建时间,也意味着immutable的变量不可修改。

3.2 Packed arrays

 写成中文大概是拥挤数组/(ㄒoㄒ)/~~ 英语不好。

也是php7优化的一部分,文档:https://blog.blackfire.io/php-7-performance-improvements-packed-arrays.html

对应数据特征:

1、key是数字

2、键以仅增长模式插入数组

对于这种数据减少的内存的消耗。

3.3 整数、浮点数内存分配

https://blog.blackfire.io/php-7-performance-improvements-ints-floats-free.html

在PHP 7中,变量在内存中的分配方式发生了巨大变化。它们从存储在堆中变为存储在堆栈内存池中

3.4 字符串优化

PHP 7 performance improvements (3/5): Encapsed strings optimization - Blackfire.io Le Blog | Fire up your web application performancep

 php5中字符串和变量混写,如"asd $a",会先分配不同缓冲区拼合后在分配到新缓冲区,最后拼合完释放所有中间缓冲区返回最后缓冲区。

hypef 五、请求及响应_第1张图片

php7中针对这样的字符串会创建堆栈,将所有需要连接的元素堆叠起来。当到达封装字符串的末尾时:使用总大小执行一次且仅一次内存分配,并将每个数据块移动到正确的位置。

hypef 五、请求及响应_第2张图片

 3.5 引用不匹配优化

PHP 7 performance improvements (4/5): References mismatch - Blackfire.io Le Blog | Fire up your web application performance

根据文章内容,使用&$value时无对应操作,php5中会再浪费内存复制数据,数据比较大时非常浪费。在PHP7中,当引擎想要从非引用变量创建引用时,它只需将后者封装到新创建的前者中,仅此而已。任何地方都没有内存副本。这是因为在PHP7中,变量在内部的工作方式非常不同,并且引用已经被深度修改。

/(ㄒoㄒ)/~~优化内容部分机翻的,没看懂。但主要意思是,由于php7变量引用的优化,貌似是变量引用时不费内存,赋值写时发生复制。

你可能感兴趣的:(php,php)