cakephp配置 为什么访问根目录失败?

CakePHP&2.x&CookBook&中文版&第二章&安装
CakePHP 很容易安装。最小安装只要有一个 web 服务器和一份 Cake 的副本,就足够了!本手册主要聚焦于在
Apache 上安装 Cake(因为 Apache 最通用), 你也可以在 LightHTTPD 或者 Microsoft IIS
之类的 web 服务器上配置运行 Cake。
必备的软件
HTTP 服务器。例如: Apache。 mod_rewrite 是推荐选择的, 但不是必须的。
PHP 5.2.8 或更高版本。
数据库引擎不是必须的,但是我们认为很多应用程序将使用它。CakePHP 支持如下数据库引擎:
MySQL (4 或更高版本)
PostgreSQL
Microsoft SQL Server
注意:所有内置的驱动都需要 PDO。你需要确定你已经正确安装了 PDO 扩展。
CakePHP 的许可是基于 MIT license
的。这意味着你能够在保持版权声明完整的前提下自由的修改、分发和重发布其源码。 你也可以在商业或封闭源代码的应用程序中包含
下载 CakePHP
有两种主要途径用来获得 CakePHP 的最新副本。你可以从主站下载(有三种格式:zip/tar.gz/tar.bz2),
或者从 git 仓库中检出代码。
要想下载最新的主版本,访问主站
并且点击 “Download
Now” 链接。
全部当前版本都寄存在
上。Github 收藏了全部的
CakePHP,并且还包含了许多的 CakePHP 的插件。 有效的 CakePHP 版本在
另外,你也可以获取最新的带有全部 bug 修正的每分钟提交的源代码。 这可以访问
仓库并克隆副本:
git clone git:///cakephp/cakephp.git
CakePHP 的一些不同操作需要使用 app/tmp 目录:模块描述、视图缓存和 session
因此,你需要确定 web 服务器用户拥有 cake 安装目录下的 app/tmp
目录和它的全部子目录的写权限。
CakePHP 可以极其简单地布署在 web 服务器的文档根目录中,也可以以你所期望的方式灵活复杂地进行布署。 这一节将覆盖
CakePHP 的三种主要安装类型: 开发、产品和高级。
开发:最容易进行。应用程序的 URLs 包括 CakePHP 的安装目录名,安全级别低。
产品:包括配置 web 服务器的文档根目录的能力、整洁的 URL,非常安全。
高级: 带有许多配置,允许你将 CakePHP 的关键目录放在文件系统的不同位置,可以在多个 CakePHP
应用程序间共享同一个 CakePHP 内核库文件夹。
开发安装是设置 Cake 的最快方法。 本例将帮助你安装一个 CakePHP 应用程序,并使其在
地址上生效。 我们假定你的文档根目录是在 /var/www/html 。
将 Cake 压缩文件的内容解压到
/var/www/html。现在在文档根目录中有了一个以下载的版本为后缀命名的文件夹(例如 cake_2.0.0)。
将这个文件夹改名为 cake_2_0. 你的开发安装在文件系统看起来结构就像下面这样:
/var/www/html/
如果 web 服务器配置正确,现在就可以通过
访问你的 Cake 应用程序了。
多个应用程序使用同一份 CakePHP
如果你开发几个应用程序,常常会感觉需要在它们之间共享一份 CakePHP 核心副本。有几个办法能达到这个目的。最简单的是使用
PHP 的 include_path。 首先,克隆 CakePHP 到一个目录。本示例中,我们使用
~/projects :
git clone git:///cakephp/cakephp.git ~/projects/cakephp
这会把 CakePHP 克隆至 ~/projects 目录。如果不想使用 git,你可以下载 zip
包,其余的步骤是相同的。 接下来,你需要找到并编辑你的 php.ini 文件。 在 *nix 系统中,常常会是
/etc/php.ini,可以使用 php -i 查找 ‘载入的配置文件’。 一旦你找到正确的
ini 文件,编辑 include_path 选项,使其包含
~/projects/cakephp/lib。 例如:
include_path = .:/home/mark/projects/cakephp/lib:/usr/local/php/lib/php
然后,启动 web 服务,在 phpinfo() 中能够看到这些修改的结果.
如果使用 windows 系统,包含路径的分隔符就是 ;(半角分号),而不是 :(半角冒号)。
完成了 include_path 设置,应用程序就能够自动找到 CakePHP。
产品安装是配置 Cake 的更灵活的方法。 这种方式允许整个域作为 CakePHP 应用程序。
本示例将帮助你在文件系统的任意位置安装 Cake,并且使其在
需要注意的是,这种安装可能需要改变 Apache web 服务器的 DocumentRoot 。
将 Cake 压缩包的内容解压到你选择的目录。在本示例中,我们假定你选择将 Cake 安装到 /cake_install。
你的产品安装的文件夹结构类似下面这样:
/cake_install/
& & webroot/ (this directory is set as the ``DocumentRoot``
directive)
& & plugins/
& & vendors/
& &.htaccess
& & index.php
& & README
程序员需要将 Apache 域名的 DocumentRoot 指向到安装目录:
DocumentRoot /cake_install/app/webroot
如果 web 服务器配置正确,将可以在
访问你的 Cake
应用程序。
高级安装和服务器精确配置
某些情况下,你希望将 CakePHP 的各个目录放在文件系统的不同位置。
这可能是由于共享主机的约束,或者是多个应用程序想要共享同一份 Cake 库。 这一节描述了如何跨文件系统铺设 CakePHP
首先,需要了解 Cake 应用程序的三个主要组成部分:
CakePHP 核心库, 在 /lib/Cake 文件夹。
应用程序代码,在 /app 文件夹。
应用程序的 web 根目录,通常在 /app/webroot 文件夹。
这些文件中的每一个都可以被放置在文件系统的任意位置,web 根目录例外,它需要通过 web 服务器访问。 你甚至可以将 web
根目录移出 app 文件件,只要你告诉 Cake 它在哪儿。
为了配置 CakePHP 安装,你需要修改如下几个文件。
/app/webroot/index.php
/app/webroot/test.php (如果你使用 测试 特性。)
有三个内容需要编辑: ROOT, APP_DIR, 和
CAKE_CORE_INCLUDE_PATH 。
ROOT 用来设置包含 app 文件夹的路径。
APP_DIR 用来设置 app 文件夹的(基本)名称。
CAKE_CORE_INCLUDE_PATH 用来设置 CakePHP 库文件夹的路径。
让我们通过运行一个示例向你展示实践中是如何进行高级安装的。假设我想设置 CakePHP 按如下方式工作:
CakePHP 核心库放置在 /usr/lib/cake 文件夹。
我的应用程序 web 根目录放置在 /var/www/mysite/ 文件夹。
我的应用程序的 app 文件夹放置在 /home/me/myapp 文件夹。
对于这种类型的安装,我需要编辑 webroot/index.php 文件(本示例中,内容添加在
/var/www/mysite/index.php 的尾部),看上去就像下面这样:
// /app/webroot/index.php (节选,注释已经被移除)&
if (!defined('ROOT')) {
& & define('ROOT', DS . 'home' . DS . 'me');&
if (!defined('APP_DIR')) {
& & define ('APP_DIR', 'myapp');&
if (!defined('CAKE_CORE_INCLUDE_PATH')) {&
& & define('CAKE_CORE_INCLUDE_PATH', DS . 'usr' . DS . 'lib');&
推荐使用 DS
常量作为文件路径的分隔符。这可以防止因使用了错误的分隔符造成的那些文件找不到的问题,并且使代码的可移植性更高。
Apache 和 mod_rewrite(以及 .htaccess)
当 CakePHP 被构建成基于 mod_rewrite
工作时(通常都是这样),我们注意到一些用户努力地去做一切能使他们的系统更好的运行的事情。
有几件可能会使运行良好的事,你应该尝试一下。 首先看看 httpd.conf (确定你编辑的是系统的
httpd.conf,而不是用户的或特定站点的)。
确定 .htaccess 被允许覆盖,并且 DocumentRoot 的 AllowOverride 被正确设置为
All。你应该看到如下的内容:
# Each directory to which Apache has access can be configured with respect&
# to which services and features are allowed and/or disabled in that&
# directory (and its subdirectories).&
# First, we configure the "default" to be a very restrictive set of&
# features.&
&Directory /&&
& & Options FollowSymLinks
AllowOverride All&
Order deny,allow&
Deny from all&
&/Directory&
确定已经正确地加载了 mod_rewrite。应该能看到如下的内容:
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
在很多系统里,这些默认是被注释掉的(行的起始是一个 #),这时你只需要删除起始的 # 符号。
修改完成后,重启 Apache 并确定设置已经生效。
检测你的 .htaccess 是不是真的在正确的目录中。
在拷贝过程可能会发生这样一种情况,因为某些操作系统隐藏了以 . 开头的文件,以致看不到它的拷贝副本。
确定你的 CakePHP 副本来自本站的 Downloads 一节指定的站点或 Git 仓库,并已经被正确地解压(通过检查
.htaccess 文件)。
Cake 根目录(需要拷贝到你的文档,重定向每件事物到 Cake app):
&IfModule mod_rewrite.c&&
& & RewriteEngine on&
& & RewriteRule
^$ app/webroot/
& & RewriteRule
(.*) app/webroot/$1 [L]&
&/IfModule&
Cake app 目录(拷贝到应用程序的顶级目录)
&IfModule mod_rewrite.c&&
& & RewriteEngine on&
& & RewriteRule
& & RewriteRule
(.*) webroot/$1
&/IfModule&
Cake webroot 目录(拷贝到应用程序的 webroot 目录)
&IfModule mod_rewrite.c&&
& & RewriteEngine On&
& & RewriteCond %{REQUEST_FILENAME} !-d&
& & RewriteCond %{REQUEST_FILENAME} !-f&
& & RewriteRule ^(.*)$ index.php [QSA,L]&
&/IfModule&
如果 CakePHP 站点仍然有 mod_rewrite 方面的问题,可能需要试着编辑虚拟主机的设置。 在 ubuntu
中,编辑 /etc/apache2/sites-available/default 文件(在它的颁发依赖中可以找到)。
在这个文件中,将 AllowOverrideNone 改成 AllowOverride
All,你将会有:
&Directory /&&
& & Options FollowSymLinks&
& & AllowOverride All&
&/Directory&&
&Directory /var/www&&
& & Options Indexes FollowSymLinks MultiViews&
& & AllowOverride All&
& & Order Allow,Deny&
& & Allow from all&
&/Directory&
在 Mac OSX,或者其它解决方案中,使用虚拟主机工具确保虚拟主机指向了你的 web 根目录。
对于更多的主机服务(GoDaddy,1and1),你的 web 服务器实际上使用了用户目录来服务,并且已经应用了
mod_rewrite。如果你把 CakePHP 安装在用户目录中()
或其它已经应用了 mod_rewrite 的 URL 结构,你需要在 CakePHP 所用的
.htaccess(/.htaccess,/app/.htaccess, /app/webroot/.htaccess) 中添加
RewriteBase 语句。
也能加入 RewriteEngine 指令到同一节中,那么 web 根目录的 .htaccess 看起来就会像下面这样:
&IfModule mod_rewrite.c&
& & RewriteEngine On
& & RewriteBase /path/to/cake/app
& & RewriteCond %{REQUEST_FILENAME} !-d
& & RewriteCond %{REQUEST_FILENAME} !-f
& & RewriteRule ^(.*)$ index.php [QSA,L]
&/IfModule&
修改的具体情况依赖于实际的设置,还可以包含与 CakePHP 无关的其它内容。更多信息请参考 Apache 在线文档。
漂亮的 URL 与 nginx
nginx 是一款流行的服务器软件,它比 Apache 使用的系统资源更少。 它的缺点是不能像 Apache 那样使用
.htaccess 文件, 它必须在可访问站点的配置中建立一些重写的 URL。 依赖于你的配置,你必须编辑这些,至少你需要让 PHP
以 FastCGI 实例的方式运行。
& & listen & 80;
& & server_
& & rewrite ^(.*) $1
& & listen & 80;
& & server_;
& & # root directive should be global
& & root & /var//public/app/webroot/;
& & access_log /var//log/access.
& & error_log /var//log/error.
& & location / {
& & & & index &index.php index.html index.
& & & & try_files $uri $uri/ /index.php?$uri&$
& & location ~ \.php$ {
& & & & include /etc/nginx/fcgi.
& & & & fastcgi_pass & &127.0.0.1:10005;
& & & & fastcgi_index & index.
& & & & fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_
基于IIS7 的 URL 重写(Windows 主机)
IIS7原生是不支持 .htaccess的。一些插件可以添加这种支持,也可以用 CakePHP 自带的 rewrite 向
IIS 导入 htaccess 规则。步骤如下:
使用 Microsoft’s Web Platform Installer (微软 web 平台安装器)安装 URL
Rewrite 2.0 模块。
在 CakePHP 文件夹建立一个文件,命名为 web.config。
使用记事本或其它 xml 安全的编辑器,将如下代码拷贝到 web.config:...
&?xml version="1.0" encoding="UTF-8"?&&
&configuration&&
& &&&system.webServer&&
& &&&rewrite&&
& & & &&&rules&
& & & & & &&&rule name="Imported Rule 1" stopProcessing="true"&&
& & & & & & & &&&match url="^(.*)$" ignoreCase="false" /&&
& & & & & & & &&&conditions logicalGrouping="MatchAll"&&
& & & & & & & & & &&&add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&
& & & & & & & & & &&&add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&
& & & & & & & & & &/conditions&&
& & & & & & & &&&action type="Rewrite" url="index.php?url={R:1}" appendQueryString="true" /&
& & & & & & & &/rule&&
& & & & & & &rule name="Imported Rule 2" stopProcessing="true"&&
& & & & & & & &&&match url="^$" ignoreCase="false" /&&
& & & & & & & &&&action type="Rewrite" url="/" /&&
& & & & & & &/rule&
& & & & & & &rule name="Imported Rule 3" stopProcessing="true"&&
& & & & & & & & &match url="(.*)" ignoreCase="false" /&&
& & & & & & & &&&action type="Rewrite" url="/{R:1}" /&&
& & & & & & &/rule&&
& & & & & &&&rule name="Imported Rule 4" stopProcessing="true"&
& & & & & & & &&&match url="^(.*)$" ignoreCase="false" /&
& & & & & & & & &conditions logicalGrouping="MatchAll"&&
& & & & & & & & & &add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&
& & & & & & & & & & &&add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&
& & & & & & & & &&/conditions&
& & & & & & & &&action type="Rewrite" url="index.php/{R:1}" appendQueryString="true" /&
& & & & & & &/rule&
& & & &/rules&&
& &&&/rewrite&&
&/system.webServer&&
&/configuration&
也可以使用 IIS Rewrite 模块的导入功能从 CakePHP 的根目录、/app/ 及 /app/webroot目录中的
.htaccess 直接导入规则——虽然一些 IIS 的编辑必须要得到这些工作。使用这种方式导入规则,IIS 将自动建立
web.config 文件。
一旦带有正确的对 IIS 友好的 rewrite 规则的 web.config 文件,CakePHP 的链接、js、css
和路由都会正确的工作。
漂亮的 URLs 和 Lighttpd
注意: 以下内容为2.0帮助文件中的内容,2.3已经删除了这一部分。 &译者注
虽然 Lighttpd 包含 rewrite 模块,但是它不同于 Apache 的 mod_rewrite。为了在使用
Lighty 获取“漂亮的 URLs”,你有两个选择。一是使用 mod_rewrite,二是通过使用 LUA 脚本和
mod_magnet。
使用 mod_rewrite:获得“漂亮的 URLs”的最快的方法是在 Lighty
的配置中添加如下脚本。再编辑一下URL,就应该没问题了。需要注意的是当 CakePHP 安装在子文件夹时这种方法无效。
$HTTP["host"] =~ "^(www\.)?$" {
& & url.rewrite-once = (
& & & & & & # if the request is for css|files etc, do not pass on to Cake
& & & & & & "^/(css|files|img|js)/(.*)" =& "/$1/$2",
& & & & & & "^([^\?]*)(\?(.+))?$" =& "/index.php/$1&$3",
& & evhost.path-pattern = "/home/%2-%1/www/www/%4/app/webroot/"
使用 mod_magnet:和 CakePHP、Lighttpd 一起使用“漂亮的 URLs”,在
/etc/lighttpd/cake中放置如下 LUA 脚本。
-- little helper function
function file_exists(path)
& local attr = lighty.stat(path)
& if (attr) then
& & & return true
& & & return false
function removePrefix(str, prefix)
& return str:sub(1,#prefix+1) == prefix.."/" and str:sub(#prefix+2)
-- prefix without the trailing slash
local prefix = ''
if (not file_exists(lighty.env["physical.path"])) then
& & -- file still missing. pass it to the fastcgi backend
& & request_uri = removePrefix(lighty.env["uri.path"], prefix)
& & if request_uri then
& & & lighty.env["uri.path"] = prefix .. "/index.php"
& & & local uriquery = lighty.env["uri.query"] or ""
& & & lighty.env["uri.query"] = uriquery .. (uriquery ~= "" and "&" or "") .. "url=" .. request_uri
& & & lighty.env["physical.rel-path"] = lighty.env["uri.path"]
& & & lighty.env["request.orig-uri"] = lighty.env["request.uri"]
& & & lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
-- fallthrough will put it back into the lighty request loop
-- that means we get the 304 handling for free. ;)
注意: 如果要在子文件夹中运行 CakePHP 安装,要在上面的脚本中设置 prefix =
‘subdirectory_name’。
然后通知 Lighttpd 你的虚拟主机是什么:
$HTTP["host"] =~ "" {
& & server.error-handler-404 = "/index.php"
& & magnet.attract-physical-path-to = ( "/etc/lighttpd/cake.lua" )
& & server.document-root = "/var/www/cake-1.2/app/webroot/"
& & # Think about getting vim tmp files out of the way too
& & url.access-deny = (
& & & & & & "~", ".inc", ".sh", "sql", ".sql", ".tpl.php",
& & & & & & ".xtmpl", "Entries", "Repository", "Root",
& & & & & & ".ctp", "empty"
让我们再来看看 CakePHP 的最佳实践。 依靠这些配置,再把你的浏览器指向
。 现在,将会看到 CakePHP 的默认主页,并有一条告知你当前数据库配置状态的消息。
恭喜!你已经完成了 建立第一个 CakePHP 应用程序的 课程。
没能正常工作?如果你看到了关于时区错误的信息,取消 app/Config/core.php
中如下这一行的注释
date_default_timezone_set('UTC');
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。您已经赞过此文了。
CakePHP应用开发 第四章 控制器——编写应用的控制逻辑(1)
发表时间:浏览量:3746评论数:0挑错数:1
控制器:编写应用程序的逻辑
控制器,跟它名字的表面意思很契合——它所起的作用是控制,督导,和管理。在CakePHP中,控制器是用来处理浏览器请求和方便模型与视图之间通信的类。它是定义应用程序逻辑的中枢之地,浏览器请求的控制处理流程就是在此定义的。
在CakePHP中,控制器的每一个公共方法(public method )都被称作操作。每个操作都代表一个地址链接。当浏览器发送一个地址链接请求时,就会调用相应的控制器操作。控制器通常会使用模型类来操作和处理用户数据。一般数据处理完毕,控制器将数据从模型中提出来,然后将它转发到合适的视图文件中去。然后视图文件会被作为响应返回给浏览器,并在浏览器中显示出来。如此,控制器就在用户,模型和视图三者中间起到协调作用。
在这一章节,我们将学习CakePHP控制器的基本要点,尤其是下面这些内容:
1,如何在控制器中实现与模型类互动。
2,如何将控制器中的数据传送到视图中去
3,如何创建控制器操作以及使给操作传输参数。
4,如何获取视图表单中的数据。
5,如何转跳到另一个操作
6,如何为所有控制器添加一个常用的功能
7,如何创建可重复用的部件,以便让我们给控制器添加功能。
与模型互动
多数情况,一个控制器只负责一个模型的逻辑处理。在第三章,我们已经见识了CakePHP是如何根据控制器的名称自动找到相应的模型的。对应的模型类自动跟控制器关联起来,我们可以在控制器中访问模型——我们无需在模型类中做特别的设置。在前一章节,我们看到了这种自动绑定的一个实例。我们创建了Tasks控制器,CakePHP就自动将对应的模型Task与控制器绑定起来。我们可以在Tasks控制器中访问Task模型,就好像模型类只是控制器的一个属性($this-&Task)。
绑定模型和控制器
在CakePHP中,所有控制器一般都有一个独立的模型类。CakePHP设计的使用方式就是这样的。CakePHP总是会依据命名规则为每一个控制器寻找一个对应的模型类,除非在控制器中对此另有明确的定义。在某些特殊的情形之下,我们的一个控制器可能没有任何对应的模型类。这时,我们必须手动设置控制器去来应对这种情况。接下来,让我们看看如何创建这种没有对应模型的控制器:
动手时间:创建无模型的控制器
1,复制一份新的CakePHP到你的网页根目录下。将文件夹命名为applogic。
2,在 /app/controllers/目录下创建一个名为books_controller.php 的新文件,向里面添加如下代码.
&?phpclass BooksController extends AppController {var $name = 'Books'; var $uses = array(); function index() {//nothing's here }
3,在 /app/views/目录里面创建一个名为books的文件夹,进入该文件夹,并创建一个名为 index.ctp 的文件,文件里面的代码如下:
&h2&Packt Book Store&/h2&&p&Coming Soon!&/p&
4,现在,访问后面这个连接,在浏览器里面查看劳动成果
怎么回事?
首先,我们创建了一个新的CakePHP工程。我们在第二章中已经知道了如何创建和配置一个新的Cake工程。在这里,因为我们无需数据库,因此,我们也就没有创建数据库的配置文件(app/config/database.php)。Cake无法找到任何数据库的配置文件,但是它还是可以正常工作的。
然后,我们创建了一个名为BooksController的控制器类。在这个控制器中,我们定义了一个名为$uses的属性。 $uses 这个属性是Cake用来定义控制器对应模型类的名称的。如果 $uses 没有定义的话,Cake会根据命名规则来寻找对应的模型类。在例子中,我们给控制器中的$uses 属性设置的是一个空数组。这意味着BooksController不用使用任何模型类。我们可以像下面这样将空值设置给$uses 。
var $uses = array();
然后,我们在BooksController的里面创建了一个名为index的操作。然后我们也为这个操作创建了对应的视图文件(app/books/index.ctp)。
index()中还没有代码。因此,当执行这个操作时,Cake只是简单的调用相应的视图文件
但有人访问这个连接 时,BooksController默认的操作(这里就是index())就会调用,相应的视图文件就会显示出来。在浏览器中效果如下。
在CakePHP中,我们有两种方式可以将控制器和模型关联起来。
1,自动绑定:CakePHP会通过默认的命名规则将模型跟控制器绑定起来。比如,名为BooksController控制器会自动与一个名为Book的模型绑定起。
2,手动绑定:如果你想要覆盖掉自动绑定,我们可以给控制器的属性$uses 赋予一组模型名称。然后在控制器中,我们就可以使用这些模型类了。
"规则优于设置“是CakePHP框架的主要哲学之一。首先推荐遵循控制器和模型的命名规则,让Cake自行将对应的控制器和模型关联起来。这可以让事情变得更简单。”
我们已经了解了第二种手动绑定的方法是如何实现的。我们给BooksController的$uses属性赋一个空值,告诉Cake这个控制器不需要任何模型类。我们也可使使用该属性为单个控制器绑定多个的模型。要实现这点,我们只要将模型名称添加到给$uses属性里面即可。
$uses = array ( 'ModelName1', 'ModelName2' ) ;
我们已经知道如何将控制器与模型绑定起来。接下来我们会了解如何使用控制器与视图互动。
相关译文来自无觅插件
还没有人赞过这篇文章
My Personal Project
Copyright & 2014 yeeyan.org&&|&&&&|&&
北京译言协力传媒科技有限公司
京ICP证号&&京公网安备99号
&&|&&&&|&&
&&|&&&&|&&&&|&&CakePHP&2.x&CookBook&中文版&第五章&控制器&之&请求和响应对象
请求和响应对象
在 CakePHP 2.0
中请求和响应对象是新的。在之前的版本中,这些对象是用数组来表示的,相关的方法分散在RequestHandlerComponent、Router、&Dispatcher&和&Controller&中。请求包含的信息上没有认证对象。在
中,CakeRequest&和&CakeResponse&用于此目的。
CakeRequest
CakeRequest&是 CakePHP
中的默认请求对象。它在请求数据中集成了一些咨询和交互特性。 CakeReqeust
建立在每个请求上,并以引用方式传递给使用请求数据的各个层。默认情况下,CakeRequest&赋值给&$this-&request,并且在控制器、视图和助手中可用。&CakeRequest&执行的部分职责包括:
将 GET、POST 和 FILES
数组处理成你熟悉的数据结构。
为请求提供相关的自省环境。类似于头信息传送、客户端 IP 地址、运行应用程序的服务器的子域/域信息等。
提供以数组成员/对象属性两种形式访问请求参数。
访问请求对象
CakeRequest
提供了数种访问请求参数的接口。一是使用对象属性,二是使用数组索引,三是通过&$this-&request-&params:
1 $this-&request-&
2 $this-&request['controller'];
3 $this-&request-&params['controller'];
上面的所有形式都访问同一个值。提供参数的多种访问形式是为了已有应用程序的迁移。所有的&路由元素&都可以通过这种形式访问。
除了&路由元素&,还经常需要访问&传递参数&和&命名参数。这此在请求对象中也都可用:
1 $this-&request-&
2 $this-&request['controller'];
3 $this-&request-&params['controller'];
上面提供了传递参数和命名参数的访问。这里有几个 CakePHP 内部使用的重要/有用的参数,这些参数也能在请求参数中找到:
plugin&处理请求的插件,没有插件时为空(null)。
controller&处理当前请求的控制器。
action&处理当前请求的动作。
prefix&当前动作的前缀。更多信息参见&前置路由&。
bare&在请求来自 requestAction()
并且包含 bare 选项时出现。Bare 请求没有要渲染的布局。
requested&当动作来自
requestAction 时出现并被设置为 true。
访问 query 参数
参数可以用&CakeRequest::$query&读取:
1 // url 为 /posts/index?page=1&sort=title
2 $this-&request-&query['page'];
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
数据都可以用&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 或者
2.2 新版功能.
在创建 REST
服务时,常常在&PUT&和&DELETE&接受请求数据。2.2
版中,所有&application/x-www-form-urlencoded请求的主体数据将自动解析并且设置为&$this-&data&的&PUT&和&DELETE&请求。如果你接收
JSON 或者 XML 数据,参看后文中如何访问这些请求的部分。
访问 XML 或者 JSON 数据
应用程序经常使用&REST&非 URL 编码的
体之间交换数据。你可以以任意格式使用&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'));
4 // 添加模式值探察器。
5 $this-&request-&addDetector('iphone', array('env' =& 'HTTP_USER_AGENT', 'pattern' =& '/iPhone/i'));
7 // 添加选项探察器。
8 $this-&request-&addDetector('internalIp', array(
'env' =& 'CLIENT_IP',
'options' =& array('192.168.0.101', '192.168.0.100')
13 // 添加回调探察器。可以是匿名函数或者定时调用。
14 $this-&request-&addDetector('awesome', array('callback' =& function ($request) {
return isset($request-&awesome);
CakeRequest&还包括&CakeRequest::domain()、&CakeRequest::subdomains()&和&CakeRequest::host()&等方法用来帮助带有子域的应用程序,让生命更简单。
下面是一些可用的内置探察器:
is('get')&检测当前的请求是否是一个
is('put')&检测当前的请求是否是一个
is('post')&检测当前的请求是否是一个
is('delete')&检测当前的请求是否是一个
is('head')&检测当前的请求是否是一个
is('options')&C检测当前的请求是否是
is('ajax')&检测当前的请求是否是来自
X-Requested-with = XmlHttpRequest.
is('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
返回正在运行的应用程序的域。
CakeRequest::subdomains($tldLength
以数组形式返回应用程序的子域。
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 =
返回请求的来源地址。
CakeRequest::clientIp($safe =
返回当前访问者的 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')
-&data('Comment.1.author', 'Mark');
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 =
找出客户端接受的内容类型,或者检测它们接受的特定内容的类型。
获取全部类型
1 $this-&request-&accepts();
检查单个类型
1 $this-&request-&accepts('application/json');
static&CakeRequest::acceptLanguage($language
获取客户端期望的全部语言,或者检测被接受的一个特定语言。
获取被接受的语言的列表
1 CakeRequest::acceptLanguage();
检测一个指定的被接受的语言
1 CakeRequest::acceptLanguage('es-es');
property&CakeRequest::$data
数据的数组。作为防止错误提示的一种方式,你可以使用&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&整合了一些原来放在&Controller、RequestHandlerComponent&和&Dispatcher&中的方法。那些旧方法已经被废弃,转而使用CakeResponse.。&CakeResponse&提供了一个接口,这个接口打包了与下面的任务相关的公用响应:
为跳转传送头信息。
传送内容类型头信息。
传送信息头信息。
传送响应内容。
变化中的响应类
默认使用&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'));
4 // 将响应的 Content-Type 设置为 vcard.
5 $this-&response-&type('vcf');
通常你将会在控制器的&beforeFilter&回调中映射附加的内容类型,如果需要,你可以利用&RequestHandlerComponent的自动视图切换功能。
有时候你需要为请求发送文件作为对其的响应。 在 2.3
版之前你可以使用&媒体视图&来实现。 在 2.3
版,MediaView
被废弃,现在你可以使用&CakeResponse::file()&传送文件来响应:
1 public function sendFile($id) {
$file = $this-&Attachment-&getFile($id);
$this-&response-&file($file['path']);
上面显示的例子要求向方法传送文件路径。 如果它是列在&CakeReponse::$_mimeTypes&中的已知文件类型,Cake
将发送适当的内容类型头信息。你也可以在调用&CakeResponse::file()&之前使用&CakeResponse::type()&方法添加新的文件类型。
如果你只想让文件显示在浏览器中,禁止文件被下载,可以指定如下选项:
1 $this-&response-&file($file['path'], array('download' =& true, 'name' =& 'foo'));
设置 headers
使用的是&CakeResponse::header()&方法。
它能以不同的参数配置调用:
1 // 设置单个 header
2 $this-&response-&header('Location', '');
4 // 设置多个 headers
5 $this-&response-&header(array('Location' =& '', '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() {
// do something.
$this-&response-&disableCache();
在 SSL 域中使用与下载文件一起使用 disableCache() 传送文件到 Internet Explorer
可能引起错误。
你也可以使用&CakeResponse::cache()&告诉客户端你想要它们缓存响应:
1 public function index() {
//do something
$this-&response-&cache('-1 minute', '+5 days');
上面的代码告诉客户端缓存响应结果5天,希望提高访客在速度方面的体验。cache()&的第一个参数是最后编辑(Last-Modifield)的值。过期(Expires)和最大年龄(Max-age)参数是以秒为单位的。还有,缓存控制(Cache-Control)设置为
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() {
// set the Cache-Control as public for 3600 seconds
$this-&response-&sharable(true, 3600);
7 public function my_data() {
// set the Cache-Control as private for 3600 seconds
$this-&response-&sharable(false, 3600);
CakeResponse&公开了设定
Cache-Control header 中的每个组件的独立方法。
过期头信息
2.1 新版功能.
还是在过期模式下,你可以设置&Expires&header,它指定响应在指定的日期/时间之后过期,时间和日期为
HTTP 规范格式。这个 header
可以使用&CakeResponse::expires()&方法设置:
1 public function view() {
$this-&response-&expires('+5 days');
这个方法还接收一个 DateTime 或者能够被 DateTime 类解析的任意字符串。
Etag 头信息
2.1 新版功能.
中的缓存校验通常用于内容不间断地更新的情况下,并且仅在缓存过期时通知应用程序生成响应内容。在这种模式下,客户端持续在缓存中存储页面,但是不直接使用它,而是每次向应用程序咨询资源是否被改变。它通常用于图片或者其它静态资源。
Etag header (调用实体
tag)是请求资源的唯一标识字符串。它非常像文件的检验和,缓存比较校验和,确定它们是否匹配。
要想享受到使用这个 header
的好处,你还必须手动调用&CakeResponse::checkNotModified()&方法,或者在应用程序中包含&RequestHandlerComponent:
1 public function index() {
$articles = $this-&Article-&find('all');
$this-&response-&etag($this-&Article-&generateHash($articles));
if ($this-&response-&checkNotModified($this-&request)) {
return $this-&
最后编辑头信息
2.1 新版功能.
还是在 HTTP 缓存校验模式下,你能够设置&Last-Modified&header
来标志一个资源最后一次被修改的日期和时间。设置这个 header 帮助 CakePHP
回复缓存客户端,基于客户端缓存的响应是否被编辑了。
要享受到使用这个 header
的好处,你还必须手动调用&CakeResponse::checkNotModified()&方法,或者在应用程序中包含&RequestHandlerComponent&::
1 public function view() {
$article = $this-&Article-&find('first');
$this-&response-&modified($article['Article']['modified']);
if ($this-&response-&checkNotModified($this-&request)) {
return $this-&
某些情况下,你可能需要使用相同的 url 提供不同的内容。 通常是由于你需要根据浏览器请求的资源的不同为其准备多个页面或者不同的
HTML 回应。你可以使用 Vary header 来应对这种情况:
1 $this-&response-&vary('User-Agent');
2 $this-&response-&vary('Accept-Encoding', 'User-Agent');
3 $this-&response-&vary('Accept-Language');
CakeResponse
CakeResponse&的最大的胜利也许是来自它使测试控制器和组件变得更容易了。代替遍布多个对象的方法,仅使用一个
对象作为委托给控制器和组件的&CakeResponse&。这会帮助你走近
‘unit’ 测试并使测试控制器更容易:
1 public function testSomething() {
$this-&controller-&response = $this-&getMock('CakeResponse');
$this-&controller-&response-&expects($this-&once())-&method('header');
除此之外,从命令行运行测试也变得更容易了,你可以使用 mock 避开由于试图在 CLI 中传送 header 引起的 ‘headers
sent’ 错误。
CakeResponse API
class&CakeResponse
CakeResponse 提供了一些与你传送给客户端的响应交互的有用的方法。
CakeResponse::header($header =
null,&$value = null)
允许你直接设置一个或多个与响应同时传送的 header。
CakeResponse::charset($charset
设置在响应中使用的字符集。
CakeResponse::type($contentType =
设置响应的内容类型。你可以使用已知类型的别名或者类型的命名。
CakeResponse::cache($since,&$time
= '+1 day')
允许你在响应中设置 cache header。
CakeResponse::disableCache()
设置这个 header 将禁止客户端缓存响应。
CakeResponse::sharable($public
= null,&$time =
将 Cache-Control header 设置成&public&或者&private&,选择性的设置资源的&max-age&指令。
2.1 新版功能.
CakeResponse::expires($time =
允许你将&Expires&header
设置为确切日期。
2.1 新版功能.
CakeResponse::etag($tag =
null,&$weak = false)
为响应资源设置唯一的&Etag&标识。
2.1 新版功能.
CakeResponse::modified($time =
以正确的格式将&Last-Modified&header
设置为一个确切日期。
2.1 新版功能.
CakeResponse::checkNotModified(CakeRequest
比较请求对象的 cache header 和 响应的 cache
header,确定其是否仍然有效。如果仍然有效,则删除所有响应内容,并传送&304
Not Modified&header。
2.1 新版功能.
CakeResponse::compress()
为请求撕开 gzip 压缩。
CakeResponse::download($filename)
允许你以附件的形式传送响应,并设置文件名。
CakeResponse::statusCode($code
允许你设置响应的状态码。
CakeResponse::body($content =
为响应设置内容主体。
CakeResponse::send()
一旦你建立了响应,调用 send() 将传送全部 heaer
和主体内容。在每个请求中,这是通过&Dispatcher&自动完成的。
CakeResponse::file($path,&$options
= array())
允许你为显示或下载设置一个文件。
2.3 新版功能.
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 cakephp 的文章

 

随机推荐