文档地址
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\RequestInterface
的 Hyperf\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",会先分配不同缓冲区拼合后在分配到新缓冲区,最后拼合完释放所有中间缓冲区返回最后缓冲区。
php7中针对这样的字符串会创建堆栈,将所有需要连接的元素堆叠起来。当到达封装字符串的末尾时:使用总大小执行一次且仅一次内存分配,并将每个数据块移动到正确的位置。
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变量引用的优化,貌似是变量引用时不费内存,赋值写时发生复制。