说明

获得请求对象

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

例子

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class User
  5. {
  6. public function hello(Request $request)
  7. {
  8. $default_name = 'webman';
  9. // 从get请求里获得name参数,如果没有传递name参数则返回$default_name
  10. $name = $request->get('name', $default_name);
  11. // 向浏览器返回字符串
  12. return response('hello ' . $name);
  13. }
  14. }

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

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

自定义请求对象

注意 此特性需要webman>=1.3.1

有时候我们需要自定义请求对象,比如我们想重写$request->get() $request->post()方法,对用户传入的数据进行转义,避免XSS注入。

新建 app/Request.php

  1. <?php
  2. namespace app;
  3. class Request extends \support\Request
  4. {
  5. public function get($name = null, $default = null)
  6. {
  7. return $this->filter(parent::get($name, $default));
  8. }
  9. public function post($name = null, $default = null)
  10. {
  11. return $this->filter(parent::post($name, $default));
  12. }
  13. public function filter($value)
  14. {
  15. if (!$value) {
  16. return $value;
  17. }
  18. if (is_array($value)) {
  19. array_walk_recursive($value, function(&$item){
  20. if (is_string($item)) {
  21. $item = htmlspecialchars($item);
  22. }
  23. });
  24. } else {
  25. $value = htmlspecialchars($value);
  26. }
  27. return $value;
  28. }
  29. }

config/app.php 中增加配置,

  1. return [
  2. // ... 这里省略了其它配置 ...
  3. 'request_class' => app\Request::class,
  4. ];

这样我们就可以使用自己的Request类来处理用户的请求了,用法类似。

  1. <?php
  2. namespace app\controller;
  3. use app\Request;
  4. class Foo
  5. {
  6. public function index(Request $request)
  7. {
  8. return response('hello webman');
  9. }
  10. }

获得请求参数get

获取整个get数组

  1. $request->get();

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

获取get数组的某一个值

  1. $request->get('name');

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

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

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

获得请求参数post

获取整个post数组

  1. $request->post();

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

获取post数组的某一个值

  1. $request->post('name');

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

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

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

获得原始请求post包体

  1. $post = $request->rawBody();

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

获取header

获取整个header数组

  1. $request->header();

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

获取header数组的某一个值

  1. $request->header('host');

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

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

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

获取cookie

获取整个cookie数组

  1. $request->cookie();

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

获取cookie数组的某一个值

  1. $request->cookie('name');

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

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

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

获得所有输入

包含了post get 的集合。

  1. $request->all();

获取指定输入值

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

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

获取部分输入数据

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

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

获取上传文件

获取整个上传文件数组

  1. $request->file();

表单类似:

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

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

  1. array (
  2. 'file1' => object(webman\Http\UploadFile),
  3. 'file2' => object(webman\Http\UploadFile)
  4. )

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

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Upload
  5. {
  6. public function files(Request $request)
  7. {
  8. foreach ($request->file() as $key => $spl_file) {
  9. var_export($spl_file->isValid()); // 文件是否有效,例如ture|false
  10. var_export($spl_file->getUploadExtension()); // 上传文件后缀名,例如'jpg'
  11. var_export($spl_file->getUploadMineType()); // 上传文件mine类型,例如 'image/jpeg'
  12. var_export($spl_file->getUploadErrorCode()); // 获取上传错误码,例如 UPLOAD_ERR_NO_TMP_DIR UPLOAD_ERR_NO_FILE UPLOAD_ERR_CANT_WRITE
  13. var_export($spl_file->getUploadName()); // 上传文件名,例如 'my-test.jpg'
  14. var_export($spl_file->getSize()); // 获得文件大小,例如 13364,单位字节
  15. var_export($spl_file->getPath()); // 获得上传的目录,例如 '/tmp'
  16. var_export($spl_file->getRealPath()); // 获得临时文件路径,例如 `/tmp/workerman.upload.SRliMu`
  17. }
  18. return response('ok');
  19. }
  20. }

注意:

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

获取特定上传文件

  1. $request->file('avatar');

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

例子

  1. <?php
  2. namespace app\controller;
  3. use support\Request;
  4. class Upload
  5. {
  6. public function file(Request $request)
  7. {
  8. $file = $request->file('avatar');
  9. if ($file && $file->isValid()) {
  10. $file->move(public_path().'/files/myfile.'.$file->getUploadExtension());
  11. return json(['code' => 0, 'msg' => 'upload success']);
  12. }
  13. return json(['code' => 1, 'msg' => 'file not found']);
  14. }
  15. }

获取host

获取请求的host信息。

  1. $request->host();

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

  1. $request->host(true);

获取请求方法

  1. $request->method();

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

获取请求uri

  1. $request->uri();

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

获取请求路径

  1. $request->path();

返回请求的path部分。

获取请求queryString

  1. $request->queryString();

返回请求的queryString部分。

获取请求url

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

  1. $request->url();

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

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

  1. $request->fullUrl();

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

注意:url()fullUrl() 没有返回协议部分(没有返回http或者https)

获取请求HTTP版本

  1. $request->protocolVersion();

返回字符串 1.1 或者1.0

获取请求sessionId

  1. $request->sessionId();

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

获取请求客户端IP

  1. $request->getRemoteIp();

获取请求客户端端口

  1. $request->getRemotePort();

获取请求客户端真实IP

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

此方法要求 webman-framework >= 1.0.2

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

$request->getRealIp();原理是:如果发现客户端IP是内网IP,则尝试从Client-IpX-Forwarded-ForX-Real-IpClient-IpVia HTTP头中获取真实IP。如果$safe_mode为false,则不判断客户端IP是否为内网IP(不安全),直接尝试从以上HTTP头中读取客户端IP数据。如果HTTP头没有以上字段,则使用$request->getRemoteIp()的返回值作为结果返回。

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

获取服务端IP

  1. $request->getLocalIp();

获取服务端端口

  1. $request->getLocalPort();

判断是否是ajax请求

  1. $request->isAjax();

判断是否是pjax请求

  1. $request->isPjax();

判断是否是期待json返回

  1. $request->expectsJson();

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

  1. $request->acceptJson();

获得请求的插件名

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

  1. $request->plugin;

此特性需要webman>=1.4.0

获得请求的应用名

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

  1. $request->app;

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

获得请求的控制器类名

获得控制器对应的类名

  1. $request->controller;

返回类似 app\controller\Index

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

获得请求的方法名

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

  1. $request->action;

返回类似 index

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