[关闭]
@a5635268 2016-02-08T20:27:06.000000Z 字数 7168 阅读 1734

Yii框架之请求处理

源码分析与使用笔记


请求组件和响应组件

http://www.yiichina.com/doc/guide/2.0/runtime-responses

请求组件

http://www.yiichina.com/doc/guide/2.0/runtime-requests

  1. # 请求组件
  2. public function actionRequest(){
  3. //更多使用方法见源码yii\web\Request
  4. $request = \Yii::$app->request; //请求组件
  5. $get = $request -> get();
  6. $name = $request -> get('name');
  7. $age = $request -> get('age',1); //如果没有的话默认给个1
  8. $post = $request -> post();
  9. # 非post和get
  10. $request = \Yii::$app->request;
  11. // 返回所有参数
  12. $params = $request->bodyParams;
  13. // 返回参数 "id"
  14. $param = $request->getBodyParam('id');
  15. //可以通过配置 yii\web\Request::parsers 属性来自定义怎样解析这些参数
  16. //获取当前请求使用的HTTP方法
  17. $method = \Yii::$app->request->method;
  18. if ($request->isAjax) { /* 该请求是一个 AJAX 请求 */ }
  19. if ($request->isGet) { /* 请求方法是 GET */ }
  20. if ($request->isPost) { /* 请求方法是 POST */ }
  21. if ($request->isPut) { /* 请求方法是 PUT */ }
  22. //假设被请求的URL是 http://example.com/admin/index.php/product?id=100, 你可以像下面描述的那样获取URL的各个部分
  23. \Yii\web\Request::url; //返回 /admin/index.php/product?id=100, 此URL不包括host info部分。
  24. \Yii\web\Request::absoluteUrl; //返回 http://example.com/admin/index.php/product?id=100, 包含host infode的整个URL。
  25. \Yii\web\Request::hostInfo; //返回 http://example.com, 只有host info部分。
  26. \Yii\web\Request::pathInfo; //返回 /product, 这个是入口脚本之后,问号之前(查询字符串)的部分。
  27. \Yii\web\Request::queryString; //返回 id=100,问号之后的部分。
  28. \Yii\web\Request::baseUrl ; //返回 /admin, host info之后, 入口脚本之前的部分。
  29. \Yii\web\Request::scriptUrl; //返回 /admin/index.php, 没有path info和查询字符串部分。
  30. \Yii\web\Request::serverName; //返回 example.com, URL中的host name。
  31. \Yii\web\Request::serverPort; //返回 80, 这是web服务中使用的端口。
  32. # 获取HTTP头
  33. // $headers 是一个 yii\web\HeaderCollection 对象
  34. $headers = \Yii::$app->request->headers;
  35. // 返回 Accept header 值
  36. $accept = $headers->get('Accept');
  37. if ($headers->has('User-Agent')) { /* 这是一个 User-Agent 头 */ }
  38. \Yii\web\Request::userAgent; //返回 User-Agent 头。
  39. \Yii\web\Request::contentType; //返回 Content-Type 头的值, Content-Type 是请求体中MIME类型数据。
  40. \Yii\web\Request::acceptableContentTypes; //返回用户可接受的内容MIME类型。 返回的类型是按照他们的质量得分来排序的。得分最高的类型将被最先返回。
  41. \Yii\web\Request::acceptableLanguages; //返回用户可接受的语言。 返回的语言是按照他们的偏好层次来排序的。第一个参数代表最优先的语言。
  42. //假如你的应用支持多语言,并且你想在终端用户最喜欢的语言中显示页面,那么你可以使用语言协商方法 yii\web\Request::getPreferredLanguage()。 这个方法通过 yii\web\Request::acceptableLanguages 在你的应用中所支持的语言列表里进行比较筛选,返回最适合的语言。
  43. //分别获取host name和客户机的IP地址
  44. $userHost = \Yii::$app->request->userHost;
  45. $userIP = \Yii::$app->request->userIP;
  46. }

响应组件

  1. public function actionResponse(){
  2. //更多使用看源码 yii\web\Response
  3. #状态码
  4. \Yii::$app->response->statusCode = 200;
  5. #获取HTTP 头部
  6. $headers = \Yii::$app->response->headers;
  7. // 增加一个 Pragma 头,已存在的Pragma 头不会被覆盖。
  8. $headers->add('Pragma', 'no-cache');
  9. // 设置一个Pragma 头. 任何已存在的Pragma 头都会被丢弃
  10. $headers->set('Pragma', 'no-cache');
  11. // 删除Pragma 头并返回删除的Pragma 头的值到数组
  12. $values = $headers->remove('Pragma');
  13. //补充: 头名称是大小写敏感的,在yii\web\Response::send()方法调用前新注册的头信息并不会发送给用户。
  14. # 响应主体
  15. //如果已有格式化好的主体字符串,可赋值到响应的yii\web\Response::content属性
  16. \Yii::$app->response->content = 'hello world!';
  17. $response = \Yii::$app->response;
  18. $response->format = \yii\web\Response::FORMAT_JSON; //默认的响应格式为:\yii\web\Response::FORMAT_HTML
  19. $response->data = ['message' => 'hello world'];
  20. //返回值会被 response 组件格式化后发送给终端用户
  21. return $this->render('index');
  22. //创建返回对象
  23. return \Yii::createObject(
  24. [
  25. 'class' => 'yii\web\Response',
  26. 'format' => \yii\web\Response::FORMAT_JSON,
  27. 'data' => [
  28. 'message' => 'hello world',
  29. 'code' => 100,
  30. ]
  31. ]
  32. );
  33. #浏览器跳转
  34. return $this->redirect('http://example.com/new', 301); //默认302,临时重定向;指定为301为永久重定向
  35. \Yii::$app->response->redirect('http://example.com/new', 301)->send(); #直接调用yii\web\Response::redirect() 再调用 yii\web\Response::send() 方法来确保没有其他内容追加到响应中
  36. #todo:ajax跳转问题
  37. #发送文件
  38. yii\web\Response::sendFile(); #发送一个已存在的文件到客户端
  39. yii\web\Response::sendContentAsFile(); #发送一个文本字符串作为文件到客户端
  40. yii\web\Response::sendStreamAsFile(); #发送一个已存在的文件流作为文件到客户端,(大文件可用)
  41. return \Yii::$app->response->sendFile('path/to/file.txt');
  42. \Yii::$app->response->sendFile('path/to/file.txt')->send();
  43. }

过滤器

http://www.yiichina.com/doc/guide/2.0/structure-filters

过滤器是 控制器操作执行之前或之后执行的对象。 例如访问控制过滤器可在动作执行之前来控制特殊终端用户是否有权限执行动作, 内容压缩过滤器可在动作执行之后发给终端用户之前压缩响应内容。
过滤器可包含 预过滤(过滤逻辑在动作之前) 或 后过滤(过滤逻辑在动作之后),也可同时包含两者。

  1. public function behaviors()
  2. {
  3. return [
  4. [
  5. 'class' => 'yii\filters\HttpCache',
  6. 'only' => ['index', 'view'],
  7. 'lastModified' => function ($action, $params) {
  8. $q = new \yii\db\Query();
  9. return $q->from('user')->max('updated_at');
  10. },
  11. ],
  12. ];
  13. }

总共有以下过滤器,需要用到的时候来看一下既可:

  1. 前置操作或后置操作: yii\base\ActionFilter
  2. 访问控制: yii\filters\AccessControl
  3. HTTP认证方法过滤器:yii\filters\auth\HttpBasicAuth 通常用在RESTful API
  4. 响应内容格式处理和语言处理: yii\filters\ContentNegotiator
  5. 客户端缓存: yii\filters\HttpCache
  6. 页面的缓存: yii\filters\PageCache
  7. 速率限制过滤器: yii\filters\RateLimiter http://www.yiichina.com/doc/guide/2.0/rest-rate-limiting
  8. HTTP请求方式过滤器: yii\filters\VerbFilter
  9. 跨域资源共享 CORS : yii\filters\Cors

通过行为完成以上过滤器类的混合

session

  1. $session = Yii::$app->session;
  2. // 检查session是否开启 ,在使用session组件的时候其实这步可以不要
  3. // 当使用session组件访问session数据时候,如果session没有开启会自动开启, 这和通过$_SESSION不同,$_SESSION要求先执行session_start()
  4. if ($session->isActive) ...
  5. // 开启session
  6. $session->open();
  7. // 关闭session
  8. $session->close();
  9. // 销毁session中所有已注册的数据
  10. $session->destroy();
  11. // 获取session中的变量值,以下用法是相同的:
  12. $language = $session->get('language');
  13. $language = $session['language'];
  14. $language = isset($_SESSION['language']) ? $_SESSION['language'] : null;
  15. // 设置一个session变量,以下用法是相同的:
  16. $session->set('language', 'en-US');
  17. $session['language'] = 'en-US';
  18. $_SESSION['language'] = 'en-US';
  19. // 删除一个session变量,以下用法是相同的:
  20. $session->remove('language');
  21. unset($session['language']);
  22. unset($_SESSION['language']);
  23. // 检查session变量是否已存在,以下用法是相同的:
  24. if ($session->has('language')) ...
  25. if (isset($session['language'])) ...
  26. if (isset($_SESSION['language'])) ...
  27. // 遍历所有session变量,以下用法是相同的:
  28. foreach ($session as $name => $value) ...
  29. foreach ($_SESSION as $name => $value) ...

当session的值为数组时,session组件会限制你直接修改数据中的单元项

  1. // 如下代码不会生效
  2. $session['captcha']['number'] = 5;
  3. $session['captcha']['lifetime'] = 3600;
  4. ##### 以下代码有效 #####
  5. // 直接使用$_SESSION有效 (确保Yii::$app->session->open() 已经调用)
  6. $_SESSION['captcha']['number'] = 5;
  7. $_SESSION['captcha']['lifetime'] = 3600;
  8. // 如下代码会生效:
  9. $session['captcha'] = [
  10. 'number' => 5,
  11. 'lifetime' => 3600,
  12. ];
  13. // 先获取session数据到一个数组,修改数组的值,然后保存数组到session中
  14. $captcha = $session['captcha'];
  15. $captcha['number'] = 5;
  16. $captcha['lifetime'] = 3600;
  17. $session['captcha'] = $captcha;
  18. // 使用ArrayObject 数组对象代替数组
  19. $session['captcha'] = new \ArrayObject;
  20. $session['captcha']['number'] = 5;
  21. $session['captcha']['lifetime'] = 3600;
  22. // 如下代码也会生效:
  23. echo $session['captcha']['lifetime'];
  24. // 使用带通用前缀的键来存储数组
  25. $session['captcha.number'] = 5;
  26. $session['captcha.lifetime'] = 3600;

Flash 数据

一次性的session数据,设置完之后只能使用一次;

自定义session存储

YII框架提供把session存储到DB,cache,redis,mongodb中的相关api,由于这些session类支持相同的API方法集,因此,切换到不同的session存储介质不需要修改项目使用session的代码。

  1. // 从"response"组件中获取cookie 集合(yii\web\CookieCollection)
  2. $cookies = Yii::$app->response->cookies;
  3. // 在要发送的响应中添加一个新的cookie
  4. $cookies->add(new \yii\web\Cookie([
  5. 'name' => 'language',
  6. 'value' => 'zh-CN',
  7. ]));
  8. // 删除一个cookie
  9. $cookies->remove('language');
  10. // 等同于以下删除代码
  11. unset($cookies['language']);

cookie默认都是加密的, 如果在开发过程中不想加密的话可以配置yii\web\Request::enableCookieValidation属性为false来禁用它

错误处理

yii 内置了一个yii\web\ErrorHandler错误处理器,所有非致命PHP错误(如,警告,提示)会转换成可获取异常

  1. use Yii;
  2. use yii\base\ErrorException;
  3. try {
  4. 10/0;
  5. } catch (ErrorException $e) {
  6. Yii::warning("Division by zero.");
  7. }
  8. // execution continues...
  9. use yii\web\NotFoundHttpException;
  10. throw new NotFoundHttpException();

yii\web\ErrorHandler 错误处理器默认使用两个视图显示错误:

@yii/views/errorHandler/error.php: 显示不包含函数调用栈信息的错误信息是使用, 当YII_DEBUG 为 false时,所有错误都使用该视图。

@yii/views/errorHandler/exception.php: 显示包含函数调用栈信息的错误信息时使用。

日志

http://www.yiichina.com/doc/guide/2.0/runtime-logging

Yii提供了一个强大的日志框架,这个框架具有高度的可定制性和可扩展性。使用这个框架,你可以轻松地记录各种类型的消息,过滤它们, 并且将它们收集到不同的目标,诸如文件,数据库,邮件。这些日志消息可以通过框架过滤,格式化,跟踪,导出,记录程序性能等等;

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注