热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CakePHP2.xCookBook中文版第五章控制器之请求和响应对象

比较请求对象的cacheheader和响应的cacheheader,确定其是否仍然有效。如果仍然有效,则删除所有响应内容,并传送304NotModifiedheader。

请求和响应对象

在 CakePHP 2.0 中请求和响应对象是新的。在之前的版本中,这些对象是用数组来表示的,相关的方法分散在RequestHandlerComponentRouter、 Dispatcher 和 Controller 中。请求包含的信息上没有认证对象。在 2.0 中,CakeRequest 和 CakeResponse 用于此目的。

CakeRequest

CakeRequest 是 CakePHP 中的默认请求对象。它在请求数据中集成了一些咨询和交互特性。 CakeReqeust 建立在每个请求上,并以引用方式传递给使用请求数据的各个层。默认情况下,CakeRequest 赋值给 $this->request,并且在控制器、视图和助手中可用。 CakeRequest 执行的部分职责包括:

  • 将 GET、POST 和 FILES 数组处理成你熟悉的数据结构。
  • 为请求提供相关的自省环境。类似于头信息传送、客户端 IP 地址、运行应用程序的服务器的子域/域信息等。
  • 提供以数组成员/对象属性两种形式访问请求参数。

访问请求对象

CakeRequest 提供了数种访问请求参数的接口。一是使用对象属性,二是使用数组索引,三是通过 $this->request->params

1 $this->request->controller; 2 $this->request['controller']; 3 $this->request->params['controller'];

上面的所有形式都访问同一个值。提供参数的多种访问形式是为了已有应用程序的迁移。所有的 路由元素 都可以通过这种形式访问。

除了 路由元素 ,还经常需要访问 传递参数 和 命名参数。这此在请求对象中也都可用:

1 $this->request->controller; 2 $this->request['controller']; 3 $this->request->params['controller'];

上面提供了传递参数和命名参数的访问。这里有几个 CakePHP 内部使用的重要/有用的参数,这些参数也能在请求参数中找到:

  • plugin 处理请求的插件,没有插件时为空(null)。
  • controller 处理当前请求的控制器。
  • action 处理当前请求的动作。
  • prefix 当前动作的前缀。更多信息参见 前置路由 。
  • bare 在请求来自 requestAction() 并且包含 bare 选项时出现。Bare 请求没有要渲染的布局。
  • requested 当动作来自 requestAction 时出现并被设置为 true。

访问 query 参数

query 参数可以用 CakeRequest::$query 读取:

1 // url 为 /posts/index?page=1&sort=title 2 $this->request->query['page']; 3 4 // 也可以用数组形式来访问 5 $this->request['url']['page']; // BC 存取器,将在未来版本中被废弃

你也可以直接访问 query 属性,或者以容错方式使用 CakeRequest::query() 读取 url query 数组。 任何不存在的键都返回空(null)值:

1 $foo = $this->request->query('value_that_does_not_exist'); 2 // $foo === null

访问 POST 数据

所有的 POST 数据都可以用 CakeRequest::$data 访问。包含 data 前缀的任意数据,其数据前缀都会被删除。例如:

1 // An input with a name attribute equal to 'data[MyModel][title]' is accessible at 2 $this->request->data['MyModel']['title'];

你也可以直接访问 data 属性,或者以容错方式使用 CakeRequest::data() 读取 data 数组。 任何不存在的键都返回空(null)值:

1 $foo = $this->request->data('Value.that.does.not.exist'); 2 // $foo == null

访问 PUT 或者 POST 数据

2.2 新版功能.

在创建 REST 服务时,常常在 PUT 和 DELETE 接受请求数据。2.2 版中,所有 application/x-www-form-urlencoded请求的主体数据将自动解析并且设置为 $this->data 的 PUT 和 DELETE 请求。如果你接收 JSON 或者 XML 数据,参看后文中如何访问这些请求的部分。

访问 XML 或者 JSON 数据

应用程序经常使用 REST 非 URL 编码的 post 体之间交换数据。你可以以任意格式使用 CakeRequest::input() 访问 input 数据。 通过提供解码功能,你可以接受反序列化形式的内容:

1 // 获取提交给 PUT/POST 动作的 JOSN 编码数据 2 $data = $this->request->input('json_decode');

自从某些反序列化方法在被调用时包含附加参数, CakeRequest::input() 也支持在附加参数中传递 json_decode 中的 ‘as array’ 参数,或者如果你想将 XML 转换成 DOM 文档对象:

1 // Get Xml encoded data submitted to a PUT/POST action 2 $data = $this->request->input('Xml::build', array('return' => 'domdocument'));

访问路径信息

CakeRequest 还提供关于应用程序路径的有用信息。 CakeRequest::$base 和 CakeRequest::$webroot 用于生成 url,并确定应用程序是否在一个子文件夹内。

检查请求

以前使用 RequestHandlerComponent 检测各种请求条件。这些方法已经被移到 CakeRequest,并且新的接口(包含多个与回调兼容的用法):

1 $this->request->is('post'); 2 $this->request->isPost();

这些方法调用返回相同的值。眼下 RequestHandler 中的方法仍然可用,但是已经被废弃并可能会在后续版本中删除。你也可以轻易地扩展有效的请求探察器,使用 CakeRequest::addDetector() 创建新类型的探察器。你可以建立四种不同类型的探察器:

  • 环境值对比 - 一个环境值对比,对比来自 env() 的值和环境变量中已知的值是否来检测所提供的值是否相等。
  • 模式值对比 - 模式值对比允许你对比来自 env() 的值和正则表达式。
  • 基于选项的对比 - 基于选项的对比使用一个选项列表建立一个正则表达式。后续调用加入一个已经定义选项的探察器来合并选项。
  • 回调探察器 - 回调发现都允许你提供一个 ‘回调’ 类型来处理检测。回调将接受请求对象作为它的唯一参数。

这有一些例子:

 1 // 添加环境探察器。  2 $this->request->addDetector('post', array('env' => 'REQUEST_METHOD', 'value' => 'POST'));  3  4 // 添加模式值探察器。  5 $this->request->addDetector('iphone', array('env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i'));  6  7 // 添加选项探察器。  8 $this->request->addDetector('internalIp', array(  9 'env' => 'CLIENT_IP', 10 'options' => array('192.168.0.101', '192.168.0.100') 11 )); 12 13 // 添加回调探察器。可以是匿名函数或者定时调用。 14 $this->request->addDetector('awesome', array('callback' => function ($request) { 15 return isset($request->awesome); 16 }));

CakeRequest 还包括 CakeRequest::domain()、 CakeRequest::subdomains() 和 CakeRequest::host() 等方法用来帮助带有子域的应用程序,让生命更简单。

下面是一些可用的内置探察器:

  • is('get') 检测当前的请求是否是一个 GET。
  • is('put') 检测当前的请求是否是一个 PUT.
  • is('post') 检测当前的请求是否是一个 POST.
  • is('delete') 检测当前的请求是否是一个 DELETE.
  • is('head') 检测当前的请求是否是一个 HEAD.
  • is('options') C检测当前的请求是否是 OPTIONS.
  • is('ajax') 检测当前的请求是否是来自 X-Requested-with = XmlHttpRequest.
  • is('ssl') 检测当前的请求是否经过 SSL
  • is('flash') 检测当前的请求是否有一个 Flash 用户代理
  • is('mobile') 检测当前的请求是否来自移动代理。

CakeRequest 和 RequestHandlerComponent

由于``CakeRequest`` 提供的过去用于 RequestHandlerComponent 的一些特性,被要求反思如何仍然适合图片。对于 2.0, RequestHandlerComponent 扮演了一个甜心爹爹的角色。在 CakeRequest 提供的功能的顶层挂了一层糖。所谓的糖就是在 RequestHandlerComponent 范围内,基于内容的类型或者 ajax 切换布局和视图。这种分隔两类的工具和糖,让你更易于区分和选择你想要的和你需要的。

与其它层面的请求互动

你可以使用 CakeRequest 反观关于请求的各种事物。除了探察器,你还能找到来自各种属性和方法的其他信息。

  • $this->request->webroot 表示 web 根目录。
  • $this->request->base 表示基目录。
  • $this->request->here 表示当前请求的完整地址。
  • $this->request->query 包含 query 字符串参数。

CakeRequest API

class CakeRequest

CakeRequest 压制 request 参数句柄和反视。

CakeRequest::domain($tldLength = 1)

返回正在运行的应用程序的域。

CakeRequest::subdomains($tldLength = 1)

以数组形式返回应用程序的子域。

CakeRequest::host()

返回应用程序的主机。

CakeRequest::method()

返回请求所用的 HTTP 方式。

CakeRequest::onlyAllow($methods)

设置允许的 HTTP 方式,如果不匹配则抛出 MethodNotAllowexException。 这个伴随传送方法的 405 输出包含必须的 ‘Allow’ 头。 The 405 response will include the required ‘Allow’ header with the passed methods

2.3 新版功能.

CakeRequest::referer($local = false)

返回请求的来源地址。

CakeRequest::clientIp($safe = true)

返回当前访问者的 IP 地址。

CakeRequest::header($name)

允许你使用此请求访问任意的 HTTP_* 头。

1 $this->request->header('User-Agent');

将返回此请求使用的用户代理。

CakeRequest::input($callback[$options])

从请求中获取 input 数据,并且可以向其传递一个解码函数。附加的参数中的解码函数可以被作为传递给 input()。

CakeRequest::data($name)

提供 点表示法 访问请求数据。允许读取和修改请求数据,调用也可以串联在一起:

1 // 修改部分请求数据,以使你能够预一些表单域。 2 $this->request->data('Post.title', 'New post') 3 ->data('Comment.1.author', 'Mark'); 4 5 // 你也能读出数据。 6 $value = $this->request->data('Post.title');


CakeRequest::query($name)

提供 点表示法 访问 url query 数据:

1 // url 为 /posts/index?page=1&sort=title 2 $value = $this->request->query('page');


2.3 新版功能.

CakeRequest::is($type)

检查一个请求是否符合某个标准。应用内置的匹配规则或者通过 CakeRequest::addDetector() 定义的任意附加规则。

CakeRequest::addDetector($name$options)

添加一个用于 is() 的探察器。更多信息参见 检查请求 。

CakeRequest::accepts($type = null)

找出客户端接受的内容类型,或者检测它们接受的特定内容的类型。

获取全部类型

1 $this->request->accepts();

检查单个类型

1 $this->request->accepts('application/json');


static CakeRequest::acceptLanguage($language = null)

获取客户端期望的全部语言,或者检测被接受的一个特定语言。

获取被接受的语言的列表

1 CakeRequest::acceptLanguage();

检测一个指定的被接受的语言

1 CakeRequest::acceptLanguage('es-es');


property CakeRequest::$data

POST 数据的数组。作为防止错误提示的一种方式,你可以使用 CakeRequest::data() 读取这个属性。

property CakeRequest::$query

query 字符串参数数组。

property CakeRequest::$params

路由元素和请求参数数组。

property CakeRequest::$here

返回当前请求的 uri。

property CakeRequest::$base

应用程序的基路径,通常是 /,除非你的应用程序放在子目录中。

property CakeRequest::$webroot

当前 web 根目录

CakeResponse

CakeResponse 是 CakePHP 中的默认响应。它包含一些在应用程序中生成 HTTP 响应的特性和功能。它也有助于测试,因为它能被 mock/stub以允许你检查将要传输的头信息。 与 CakeRequest 类似, CakeResponse 整合了一些原来放在 ControllerRequestHandlerComponent 和 Dispatcher 中的方法。那些旧方法已经被废弃,转而使用CakeResponse.。 CakeResponse 提供了一个接口,这个接口打包了与下面的任务相关的公用响应:

  • 为跳转传送头信息。
  • 传送内容类型头信息。
  • 传送信息头信息。
  • 传送响应内容。

变化中的响应类

CakePHP 默认使用 CakeResponse。 CakeResponse 对于使用类是灵活透明的。不过如果你需要在应用程序的特定类中替换它,你使用自己的类覆盖或替换 CakeResponse 。通过替换在 index.php 中使用的 CakePHPResponse。

这会使你的应用程序中的所有控制器都用 CustomResponse 代替 CakeResponse。 你也可以在控制器中设置 $this->response 来替换 response 实例。 在测试过程中覆盖这个 response 对象很有用,它允许你 stub 与 header() 一起工作的方法。 更多的信息请参见 CakeResponse 与测试 一节。

处理内容类型

你可以使用 CakeResponse::type() 控制应用程序响应的 内容类型(Content-Type)。如果你的应用程序需要处理没有内置在 CakeResponse 中的内容类型,你还可以使用 type() 映射它们:

1 // 添加 vCard 类型 2 $this->response->type(array('vcf' => 'text/v-card')); 3 4 // 将响应的 Content-Type 设置为 vcard. 5 $this->response->type('vcf');

通常你将会在控制器的 beforeFilter 回调中映射附加的内容类型,如果需要,你可以利用 RequestHandlerComponent的自动视图切换功能。

传输文件

有时候你需要为请求发送文件作为对其的响应。 在 2.3 版之前你可以使用 媒体视图 来实现。 在 2.3 版,MediaView 被废弃,现在你可以使用 CakeResponse::file() 传送文件来响应:

1 public function sendFile($id) { 2 $file = $this->Attachment->getFile($id); 3 $this->response->file($file['path']); 4 }

上面显示的例子要求向方法传送文件路径。 如果它是列在 CakeReponse::$_mimeTypes 中的已知文件类型,Cake 将发送适当的内容类型头信息。你也可以在调用 CakeResponse::file() 之前使用 CakeResponse::type() 方法添加新的文件类型。

如果你只想让文件显示在浏览器中,禁止文件被下载,可以指定如下选项:

1 $this->response->file($file['path'], array('download' => true, 'name' => 'foo'));

设置 header

设置 headers 使用的是 CakeResponse::header() 方法。 它能以不同的参数配置调用:

1 // 设置单个 header 2 $this->response->header('Location', 'http://example.com'); 3 4 // 设置多个 headers 5 $this->response->header(array('Location' => 'http://example.com', 'X-Extra' => 'My header')); 6 $this->response->header(array('WWW-Authenticate: Negotiate', 'Content-type: application/pdf'));

一个 header 被设置多次,将只保留最后一次的设置,就像普通的 header 调用一样。当调用CakeResponse::header() 时,Header 并没有发送。它们在响应被真实的发送之前只是被缓冲了。

与浏览器缓存交互

有时你需要禁止浏览器缓存控制器动作的结果。 CakeResponse::disableCache() 就是用来干这个的::

1 public function index() { 2 // do something. 3 $this->response->disableCache(); 4 }

警告

在 SSL 域中使用与下载文件一起使用 disableCache() 传送文件到 Internet Explorer 可能引起错误。

你也可以使用 CakeResponse::cache() 告诉客户端你想要它们缓存响应:

1 public function index() { 2 //do something 3 $this->response->cache('-1 minute', '+5 days'); 4 }

上面的代码告诉客户端缓存响应结果5天,希望提高访客在速度方面的体验。cache() 的第一个参数是最后编辑(Last-Modifield)的值。过期(Expires)和最大年龄(Max-age)参数是以秒为单位的。还有,缓存控制(Cache-Control)设置为 public。

HTTP 缓存微调

提高应用程序的访问速度的一个又好又容易的办法是使用 HTTP 缓存。 在这种模式下,你只需要通过设置几个 header (如编辑时间、响应实体及其它)来帮助客户端决定是否使用响应的缓存副本。

反对使用代码逻辑处理 缓存和在数据改变时失效(刷新),HTTP 的过期和校验两种模式常常比自己管理缓存更简单。

除了 CakeResponse::cache() ,你还可以使用另外一些方法实现 HTTP 缓存头来利用浏览器或反向代理缓存。

缓存控制 头信息

2.1 新版功能.

在过期模式下,header 包括多个能够使浏览器或代理使用缓存内容的标志。一个 Cache-Control header 如下:

1 Cache-Control: private, max-age=3600, must-revalidate

CakeResponse 类及一些产生最终有效的 Cache-Control header 工具方法帮助你设置这些头信息。其中的第一个是CakeResponse::sharable() 方法, 它标志一个响应是否考虑在不同的用户或者客户端共享。 此方法实际控制 header 的 public 或者 private 部分。将响应设置成 private 标志着它的全部或部分是设计给单个用户的。要共享缓存需要将 control 指令设置为 public。

此方法的第二个参数用于指定缓存的 Max-age ,它声明响应在多少秒后过期。

 1 public function view() {  2 ...  3 // set the Cache-Control as public for 3600 seconds  4 $this->response->sharable(true, 3600);  5 }  6  7 public function my_data() {  8 ...  9 // set the Cache-Control as private for 3600 seconds 10 $this->response->sharable(false, 3600); 11 }

CakeResponse 公开了设定 Cache-Control header 中的每个组件的独立方法。

过期头信息

2.1 新版功能.

还是在过期模式下,你可以设置 Expires header,它指定响应在指定的日期/时间之后过期,时间和日期为 HTTP 规范格式。这个 header 可以使用 CakeResponse::expires() 方法设置:

1 public function view() { 2 $this->response->expires('+5 days'); 3 }
        
        
    
推荐阅读
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 本文介绍了DataTables插件的官方网站以及其基本特点和使用方法,包括分页处理、数据过滤、数据排序、数据类型检测、列宽度自动适应、CSS定制样式、隐藏列等功能。同时还介绍了其易用性、可扩展性和灵活性,以及国际化和动态创建表格的功能。此外,还提供了参数初始化和延迟加载的示例代码。 ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
author-avatar
薇薇VS安安北_396
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有