说明

获得请求对象

webman 会自动将请求对象注入到 action 方法第一个参数中,例如

例子

<?php
namespace app\controller;

use support\Request;

class UserController
{public function hello(Request $request)
    {
        $default_name = 'webman';
        // 从 get 请求里获得 name 参数,如果没有传递 name 参数则返回 $default_name
        $name = $request->get('name', $default_name);
        // 向浏览器返回字符串
        return response('hello' . $name);
    }
}

通过 $request 对象我们能获取到请求相关的任何数据。

有时候我们想在其它类中获取当前请求的 $request 对象,这时候我们只要使用助手函数 request() 即可;

获得请求参数 get

获取整个 get 数组

$request->get();

如果请求没有 get 参数则返回一个空的数组。

获取 get 数组的某一个值

$request->get('name');

如果 get 数组中不包含这个值则返回 null。

你也可以给 get 方法第二个参数传递一个默认值,如果 get 数组中没找到对应值则返回默认值。例如:

$request->get('name', 'tom');

获得请求参数 post

获取整个 post 数组

$request->post();

如果请求没有 post 参数则返回一个空的数组。

获取 post 数组的某一个值

$request->post('name');

如果 post 数组中不包含这个值则返回 null。

与 get 方法一样,你也可以给 post 方法第二个参数传递一个默认值,如果 post 数组中没找到对应值则返回默认值。例如:

$request->post('name', 'tom');

助手函数 input()

与 $request->input()函数类似, 可以获取到所有参数, input()助手函数一共有两个参数:

  1. name: 获取的参数名称 (如果为空, 可以获取所有参数的数组)
  2. default: 默认值 (通过第一个参数获取失败后, 会使用该参数的值)

例如

// 获取参数 name
$name = input('name');
// 获取参数 name, 如果不存在则使用默认值
$name = input('name','张三');
// 获取全部参数
$all_params = input();

获得原始请求 post 包体

$post = $request->rawBody();

这个功能类似与 php-fpm里的 file_get_contents("php://input");操作。用于获得 http 原始请求包体。这在获取非 application/x-www-form-urlencoded 格式的 post 请求数据时很有用。

获取 header

获取整个 header 数组

$request->header();

如果请求没有 header 参数则返回一个空的数组。注意所有 key 均为小写。

获取 header 数组的某一个值

$request->header('host');

如果 header 数组中不包含这个值则返回 null。注意所有 key 均为小写。

与 get 方法一样,你也可以给 header 方法第二个参数传递一个默认值,如果 header 数组中没找到对应值则返回默认值。例如:

$request->header('host', 'localhost');

获取 cookie

获取整个 cookie 数组

$request->cookie();

如果请求没有 cookie 参数则返回一个空的数组。

获取 cookie 数组的某一个值

$request->cookie('name');

如果 cookie 数组中不包含这个值则返回 null。

与 get 方法一样,你也可以给 cookie 方法第二个参数传递一个默认值,如果 cookie 数组中没找到对应值则返回默认值。例如:

$request->cookie('name', 'tom');

获得所有输入

包含了post get 的集合。

$request->all();

获取指定输入值

post get 的集合中获取某个值。

$request->input('name', $default_value);

获取部分输入数据

post get 的集合中获取部分数据。

// 获取 username 和 password 组成的数组,如果对应的 key 没有则忽略
$only = $request->only(['username', 'password']);
// 获得除了 avatar 和 age 以外的所有输入
$except = $request->except(['avatar', 'age']);

通过控制器参数获得输入

<?php
namespace app\controller;
use support\Response;

class UserController
{public function create(string $name, int $age = 18): Response
    {return json(['name' => $name, 'age' => $age]);
    }
}

代码逻辑类似于

<?php
namespace app\controller;
use support\Request;
use support\Response;

class UserController
{public function create(Request $request): Response
    {$name = $request->input('name');
        $age = (int)$request->input('age', 18);
        return json(['name' => $name, 'age' => $age]);
    }
}

更多信息请参考 控制器参数绑定

获取上传文件

提示
上传文件需要使用 multipart/form-data 格式的表单

获取整个上传文件数组

$request->file();

表单类似:

<form method="post" action="http://127.0.0.1:8787/upload/files" enctype="multipart/form-data" />
<input name="file1" multiple="multiple" type="file">
<input name="file2" multiple="multiple" type="file">
<input type="submit">
</form>

$request->file()返回的格式类似:

array ('file1' => object(webman\Http\UploadFile),
    'file2' => object(webman\Http\UploadFile)
)

他是一个 webman\Http\UploadFile 实例的数组。webman\Http\UploadFile类继承了 PHP 内置的 SplFileInfo 类,并且提供了一些实用的方法。

<?php
namespace app\controller;

use support\Request;

class UploadController
{public function files(Request $request)
    {foreach ($request->file() as $key => $spl_file) {var_export($spl_file->isValid()); // 文件是否有效,例如 ture|false
            var_export($spl_file->getUploadExtension()); // 上传文件后缀名,例如 'jpg'
            var_export($spl_file->getUploadMimeType()); // 上传文件 mine 类型,例如 'image/jpeg'
            var_export($spl_file->getUploadErrorCode()); // 获取上传错误码,例如 UPLOAD_ERR_NO_TMP_DIR UPLOAD_ERR_NO_FILE UPLOAD_ERR_CANT_WRITE
            var_export($spl_file->getUploadName()); // 上传文件名,例如 'my-test.jpg'
            var_export($spl_file->getSize()); // 获得文件大小,例如 13364,单位字节
            var_export($spl_file->getPath()); // 获得上传的目录,例如 '/tmp'
            var_export($spl_file->getRealPath()); // 获得临时文件路径,例如 `/tmp/workerman.upload.SRliMu`
        }
        return response('ok');
    }
}

注意:

  • 文件被上传后会被命名为一个临时文件,类似 /tmp/workerman.upload.SRliMu
  • 上传文件大小受到 defaultMaxPackageSize 限制,默认 10M,可在 config/server.php 文件中修改 max_package_size 更改默认值。
  • 请求结束后临时文件将被自动清除
  • 如果请求没有上传文件则 $request->file() 返回一个空的数组
  • 上传的文件不支持 move_uploaded_file() 方法,请使用 $file->move()方法代替,参见下面的例子

获取特定上传文件

$request->file('avatar');

如果文件存在的话则返回对应文件的 webman\Http\UploadFile 实例,否则返回 null。

例子

<?php
namespace app\controller;

use support\Request;

class UploadController
{public function file(Request $request)
    {$file = $request->file('avatar');
        if ($file && $file->isValid()) {$file->move(public_path().'/files/myfile.'.$file->getUploadExtension());
            return json(['code' => 0, 'msg' => 'upload success']);
        }
        return json(['code' => 1, 'msg' => 'file not found']);
    }
}

获取 host

获取请求的 host 信息。

$request->host();

如果请求的地址是非标准的 80 或者 443 端口,host 信息可能会携带端口,例如example.com:8080。如果不需要端口第一个参数可以传入true

$request->host(true);

获取请求方法

 $request->method();

返回值可能是 GETPOSTPUTDELETEOPTIONSHEAD 中的一个。

获取请求 uri

$request->uri();

返回请求的 uri,包括 path 和 queryString 部分。

获取请求路径

$request->path();

返回请求的 path 部分。

获取请求 queryString

$request->queryString();

返回请求的 queryString 部分。

获取请求 url

url()方法返回不带有Query 参数 的 URL。

$request->url();

返回类似//www.workerman.net/workerman-chat

fullUrl()方法返回带有Query 参数 的 URL。

$request->fullUrl();

返回类似//www.workerman.net/workerman-chat?type=download

注意
url()fullUrl() 没有返回协议部分(没有返回 http 或者 https)。
因为浏览器里使用 //example.com 这样以 // 开头的地址会自动识别当前站点的协议,自动以 http 或 https 发起请求。

如果你使用了 nginx 代理,请将 proxy_set_header X-Forwarded-Proto $scheme; 加入到 nginx 配置中,参考 nginx 代理
这样就可以用 $request->header('x-forwarded-proto'); 来判断是 http 还是 https,例如:

echo $request->header('x-forwarded-proto'); // 输出 http 或 https

获取请求 HTTP 版本

$request->protocolVersion();

返回字符串 1.1 或者1.0

获取请求 sessionId

$request->sessionId();

返回字符串,由字母和数字组成

获取请求客户端 IP

$request->getRemoteIp();

获取请求客户端端口

$request->getRemotePort();

获取请求客户端真实 IP

$request->getRealIp($safe_mode=true);

当项目使用代理 (例如 nginx) 时,使用 $request->getRemoteIp() 得到的往往是代理服务器 IP(类似 127.0.0.1 192.168.x.x) 并非客户端真实 IP。这时候可以尝试使用 $request->getRealIp() 获得客户端真实 IP。

$request->getRealIp()会尝试从 HTTP 头的 x-forwarded-forx-real-ipclient-ipx-client-ipvia 字段中获取真实 IP。

由于 HTTP 头很容伪造,所以此方法获得的客户端 IP 并非 100% 可信,尤其是 $safe_mode 为 false 时。透过代理获得客户端真实 IP 的比较可靠的方法是,已知安全的代理服务器 IP,并且明确知道携带真实 IP 是哪个 HTTP 头,如果 $request->getRemoteIp() 返回的 IP 确认为已知的安全的代理服务器,然后通过 $request->header('携带真实 IP 的 HTTP 头') 获取真实 IP。

获取服务端 IP

$request->getLocalIp();

获取服务端端口

$request->getLocalPort();

判断是否是 ajax 请求

$request->isAjax();

判断是否是 pjax 请求

$request->isPjax();

判断是否是期待 json 返回

$request->expectsJson();

判断客户端是否接受 json 返回

$request->acceptJson();

获得请求的插件名

非插件请求返回空字符串''

$request->plugin;

获得请求的应用名

单应用的时候始终返回空字符串 '' 多应用 的时候返回应用名

$request->app;

因为闭包函数不属于任何应用,所以来自闭包路由的请求 $request->app 始终返回空字符串''
闭包路由参见 路由

获得请求的控制器类名

获得控制器对应的类名

$request->controller;

返回类似 app\controller\IndexController

因为闭包函数不属于任何控制器,所以来自闭包路由的请求 $request->controller 始终返回空字符串''
闭包路由参见 路由

获得请求的方法名

获得请求对应的控制器方法名

$request->action;

返回类似 index

因为闭包函数不属于任何控制器,所以来自闭包路由的请求 $request->action 始终返回空字符串''
闭包路由参见 路由

重写参数

有时候我们想重写请求的参数,例如将请求过滤,然后重新赋值给请求对象,这时候我们可以使用 setGet() setPost() setHeader() 方法。

重写 GET 参数

$request->get(); // 假设得到 ['name' => 'tom', 'age' => 18]
$request->setGet(['name' => 'tom']);
$request->get(); // 最终得到 ['name' => 'tom']

注意
如例子所示,setGet()是重写所有 GET 参数,setPost() setHeader() 也是同样的行为。

重写 POST 参数

$post = $request->post();
foreach ($post as $key => $value) {$post[$key] = htmlspecialchars($value);
}
$request->setPost($post);
$request->post(); // 得到过滤后的 post 参数

重写 HEADER 参数

$request->setHeader(['host' => 'example.com']);
$request->header('host'); // 输出 example.com