CakePHP 2.x CookBook 中文版 第三章 入门

入门

CakePHP 框架为应用程序提供了坚实的基础。它控制着所有方面,从用户的初始请求直到 web 页面的最终渲染。由于本框架遵循 MVC 原则,使得自定义和扩展应用程序变得更容易。

本框架还提供了一个基本的原始结构,从文件名到数据库表名,保持了应用程序的一致性和逻辑性。这个概念简单而强劲。遵循规则,就会知道东西都在哪儿,都是怎样组织的。

体验和学习 CakePHP 的最好办法是坐下来做点什么。我们将开始构建一个简单的博客系统。

博客课程

欢迎来到 CakePHP。你也许浏览这个课程因为你想了解 CakePHP 如何工作的更多信息。我们旨在提高生产力,使编程更愉悦:我们希望你深入代码,以了解这一点。

本课程将引领你创建一个简单的博客应用程序。我们获取和安装 CakePHP,建立和配置数据库,并且建立列表、新建、编辑和删除博客贴子的逻辑。

以下是我们需要的东西:

  1. 一个运行中的 web 服务器。假定使用的是 Apache,不过使用其它 web 服务器的说明也是类似的。我们可能要做一点服务器配置,但是大多数人完全不需要任何配置就可以运行 Cake。 请确认你拥有 PHP 5.2.8 或更高版本。
  2. 一个数据库服务器。在本课程中我们将使用 MySQL 服务器。你需要了解足够的建立数据库的 SQL 信息:Cake 将从那得到控制权。如果我们使用 MySQL,还要确认 PHP 已经启用了 pdo_mysql 。
  3. 基本的 PHP 知识。最好还懂面向对象编程:但是如果你只是个编程爱好者,也不必担心。
  4. 最后,需要有一点 MVC 编程模式的基本知识。在 理解 模型 - 视图 - 控制器 一节能找到一个快速预览。不用担心,大约只有半页左右。

让我们开始吧!

获得 Cake

首先让我们取得一份新鲜的 Cake 代码的拷贝。

要得到新鲜的下载,访问 Github 上的 CakePHP 项目: http://github.com/cakephp/cakephp/downloads 并且下载 2.0 的最新版本。

也可以使用 git 克隆代码仓库: git。

1 git clone git://github.com/cakephp/cakephp.git

不管是怎样下载的,都把代码放进 DocumentRoot 之内。一旦完成,目录内的东西看起来应该像下面这样:

/path_to_document_root
    /app
    /lib
    /plugins
    /vendors
    .htaccess
    index.php
    README

现在也许是多学一点儿关于 CakePHP 目录结构如何工作的好时候:浏览 CakePHP 的文件夹结构 一节。

建立博客数据库

接着,设置博客的基本数据库。如果你还不曾这么做,建立一个为本教程所用的空数据库,名称任选。现在,建立一个单表用来存储博客贴子。我们也抛出几个贴子用于测试。在数据库上执行如下语句:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

表名和列名并非随意指定的。如果遵循 Cake 的数据库命名规则和 Cake 类命名规则(两者的要点都在 CakePHP 约定 一节),能够得到额外的好处:附送的功能并且无需配置。Cake 足够灵活以适应糟糕的遗留数据库结构,但是遵循规则会节省很多时间。

更多的信息参见 CakePHP 约定 一节,简单点说,只要把表命名为“posts“就能自动与 Post 模块挂靠在一起,而 modified 和 created 列则会被 Cake 自动管理。

Cake 数据库配置

步步高升:让我们告诉 Cake 数据库在哪儿以及如何连接它。对于多数情况,这是唯一的配置。

/app/Config/database.php.default 是 CakePHP 数据库配置文件的一个副本,在同一目录中复制这个文件,命名为database.php 。

这个配置文件非常简单:只要用实际的值替换数组 $default 的值。下面是一个完整的配置数组的示例:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

保存了新的 database.php 文件之后,打开浏览器浏览 Cake 欢迎页面。上面将会显示数据库连接文件被找到,并且已能正确地连接到数据库。

注解

记得你需要 PDO,并且 php.ini 文件中 pdo_mysql 必须可用(enabled)。

可选的配置

另外还有三项配置。许多开发人员完成了长长的列表项,但是它们不包含在本教程中。一是定义一个自定义字符串(salt)用于安全哈希。二是定义一个自定义数字(seed)用于加密。三是允许 CakePHP 写入它的 tmp 文件夹。

安全 salt 用来生成哈希值。编辑 /app/Config/core.php 文件的 187 行修改默认的 salt 值。什么样的值不会有麻烦呢?长到不容易被猜到的值。

1 /**
2  * A random string used in security hashing methods.
3  */
4 Configure::write('Security.salt', 'pl345e-P45s_7h3*S@l7!');

密码种子用于加/解密字符串。编辑 /app/Config/core.php 的 192 行修改默认的 seed 值。什么样的值不会有麻烦呢?长到不容易被猜到的值。

1 /**
2  * A random numeric string (digits only) used to encrypt/decrypt strings.
3  */
4 Configure::write('Security.cipherSeed', '7485712659625147843639846751');

最后一项任务是使 app/tmp 目录允许 web 写入。最好的办法是先用(<?php echo `whoami`; ?>)找出运行 web 服务器的用户,然后将 app/tmp 的所有者指向该用户。在 *nix 系统中运行类似下面的命令:

1 $ chown -R www-data app/tmp

如果囿于某些条件而不能写入这个文件夹,你会收到一个不能使用产品模式的警告。

mod_rewrite 说明

偶尔有用户会遇到 mod_rewrite 方面的问题,所以我们在这做个简要说明。如果 CakePHP 欢迎页面有点儿可笑(没有图片或 CSS 样式),意味着系统中缺少 mod_rewrite 功能。有一些对正确运行有帮助的提示: :

确定 .htaccess 覆盖是被允许的:在 httpd.conf 中每个目录有一个节定义这条规则。确认是在正确的目录中把AllowOverride 设置 All。出于安全和执行方面的原因,不要在 <Directory /> 中把 AllowOverride 设置为All。替代方案是寻找指向所用 web 站点目录的 <Directory> 块。

  1. 确定 .htaccess 覆盖是被允许的:在 httpd.conf 中每个目录有一个节定义这条规则。确认是在正确的目录中把AllowOverride 设置 All。出于安全和执行方面的原因,不要在 <Directory /> 中把 AllowOverride 设置为All。替代方案是寻找指向所用 web 站点目录的 <Directory> 块。

  2. 确认编辑了正确的 httpd.conf,而不是某个用户或特别站点的 httpd.conf。

  3. 有些情况下,可能拿到的是一个不带 .htaccess 文件的 CakePHP 副本。出现这种情况的原因是由于一些操作系统隐藏(不显示)以 . 开头的文件,以致拷贝时没有拷贝这个文件。确保 CakePHP 的副本来自下载一节的站点或 git 仓库。

  4. 确认 Apache 正确的加载了 mod_rewrite。应该可以在 httpd.conf 中看到如下的内容::

    1 LoadModule rewrite_module             libexec/httpd/mod_rewrite.so

    或者(在 Apache 1.3)中

    1 AddModule             mod_rewrite.c

     

如果不想或不能让运行中的系统使用 mod_rewrite(及其它兼容模块),需要使用 CakePHP 内置的漂亮 URLs。取消/app/Config/core.php 文件中如下一行的注释:

1 Configure::write('App.baseUrl', env('SCRIPT_NAME'));

同时删除这几个 .htaccess 文件:

/.htaccess
/app/.htaccess
/app/webroot/.htaccess

这会用类似 www.example.com/index.php/controllername/actionname/param 的 URL 代替 www.example.com/controllername/actionname/param。

如果 CakePHP 安装在 Apache 以外的 web 服务器上,可以在 高级安装 一节找到工作在 URL 重写机制下的介绍。

接下来的 博客课程 —— 加入一个层,将开始第一个 CakePHP 应用程序。

博客课程 —— 加入一个层

建立 Post 模型

模型(model)类是 CakePHP 应用程序的面包和奶油。通过建立与数据库结合的模型类,我们就有了随后放置所需的显示、添加、编辑和删除操作的基础。

CakePHP 的模型类放在 /app/Model 文件夹,我们建立的文件将被存为 /app/Model/Post.php。完整的文件类似于:

1 class Post extends AppModel {
2 }

在 CakePHP 中命名规则非常重要。通过把类命名为 Post,CakePHP 会自动认定这个模型将被用在 PostsController 中,而且会与名为 posts 的数据库表关联。.

注解

如果 CakePHP 不能在 /app/Model 文件夹内找到相对应的文件,它会动态地建立一个模型对象。也就是说,如果不慎写错了文件名(例如 post.php 或者 posts.php),CakePHP 就不认识所有的设置并使用默认的设置代替它。

关于模型的更多信息,诸如表前缀、回调和数据校验,请参阅手册中 模型 一章。

建立 Posts 控制器

接着我们为贴子建立一个控制器。这个控制器是发生贴子交互的地方。简单地说,它就是完成运行模型和获得贴子相关工作的地方。我们将在 /app/Controller 目录的 PostsController.php 文件中放置一个控制器类。类的基本内容类似于:

1 class PostsController extends AppController {
2     public $helpers = array('Html', 'Form');
3 }

现在在控制器中添加一个动作。控制器中的动作通常实现单一的功能或接口。例如,当用户请求http://www.example.com/post/index(这个和 http://www.example.com/post 相同),他们可能期待看见一个贴子列表。这个动作的代码类似于:

1 class PostsController extends AppController {
2     public $helpers = array('Html', 'Form');
3 
4     public function index() {
5         $this->set('posts', $this->Post->find('all'));
6     }
7 }

我来解释一下这个动作。通过在 PostsController 中定义一个函数 index(),用户现在就能够通过向www.example.com/posts/index 提交访问程序逻辑。类似地,如果定义一个函数叫 foobar(),用户就能够访问 www.example.com/posts/index。

警告

以短小的方式命名控制器和动作是一种诱惑,要抑制这种诱惑。遵循 CakePHP 的命名规则(以复数命名控制器等)建立易读、易理解的动作名称。随后可以通过``路由``映射 URLs 到代码。

上例中index动作中使用 set() 方法从控制器向视图(后面会创建)传递数据。设置视图那一行中名为 ‘posts’ 的变量等于 Post 模型的 find('all') 方法的返回值。由于遵循了 Cake 的命名规则,Posts 模型自动可用($this->Post)。

要学习 Cake 控制器的更多内容,请浏览 控制器 一章。

建立 Post 视图

现在已经有了数据流、模型、程序逻辑和定义数据流向的控制器。我们要建立与上面例子中的 index 动作对应的视图。

Cake 视图仅是呈现应用程序布局的片段。对于多数应用程序,视图是混合了 PHP 的 HTML,但是它也可以是 XML、CSV,甚至是二进制数据。

布局是包装视图的处理显示的代码,能够定义和切换,但是现在,我们使用默认的布局。

还记得上一节是如何使用 set() 方法给视图中的 ‘posts’ 变量赋值的吗?所传递的数据类似于:

复制代码
 1 // print_r($posts) output:
 2 
 3 Array
 4 (
 5     [0] => Array
 6         (
 7             [Post] => Array
 8                 (
 9                     [id] => 1
10                     [title] => The title
11                     [body] => This is the post body.
12                     [created] => 2008-02-13 18:34:55
13                     [modified] =>
14                 )
15         )
16     [1] => Array
17         (
18             [Post] => Array
19                 (
20                     [id] => 2
21                     [title] => A title once again
22                     [body] => And the post body follows.
23                     [created] => 2008-02-13 18:34:56
24                     [modified] =>
25                 )
26         )
27     [2] => Array
28         (
29             [Post] => Array
30                 (
31                     [id] => 3
32                     [title] => Title strikes back
33                     [body] => This is really exciting! Not.
34                     [created] => 2008-02-13 18:34:57
35                     [modified] =>
36                 )
37         )
38 )
复制代码

Cake 的视图文件存储在 /app/View 目录下与控制器名称(去掉了 controller 后缀)同名的文件夹中(现在的情况下,要创建 /app/View/Posts 文件夹)。使用漂亮的表格格式化数据,其视图类似于:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

希望这看起来挺简单。

你可能已经注意到例子中所用的那个调用 $this->HTML 的对象,这是 CakePHP 中 ‘HtmlHelper’ 的一个实例。CakePHP 带有一个生成类似链接、表单输出、JavaScript 和 Ajax 快照的视图助手集合。在 助手 一节你能学到更多如何使用它们的方法,现在要重点注意的是 link() 方法,它能用给定的标题(第一个参数)和 URL (第二个参数)生成 HTML 链接。

推荐使用数组格式在 CakePHP 中指定 URLs。在“路由”一节对此有更多的解释。使用数组格式处理 URLs 可以获得 CakePHP 服务器的路由兼容性。也可以用 /controller/action/param1/param2 的格式将 URLs 关联到应用程序。

现在,让你的浏览器指向 http://www.example.com/posts/index 。你会看到带有标题和帖子列表的格式正确的视图。

如果你点击了我们建立的这个视图中的某个链接(它将一个帖子标题链接到 URL /posts/view/some_id), 你应该会发现 CakePHP 会报告那个 action 还没有定义。 如果你没有收到这个报告,表明有些事情可能出错了,或者你竟然已经定义了它,这是很诡异的一种情形^_^。 现在,让我们在 PostsController 中建立它:

复制代码
 1 class PostsController extends AppController {
 2     public $helpers = array('Html', 'Form');
 3 
 4     public function index() {
 5          $this->set('posts', $this->Post->find('all'));
 6     }
 7 
 8     public function view($id = null) {
 9         $this->Post->id = $id;
10         $this->set('post', $this->Post->read());
11     }
12 }
复制代码

set() 调用看上去有点眼熟。需要注意的是,我们在此优先使用 read() 而不是 find('all'),这是因为我们仅仅要得到一条帖子信息。

还要注意,我们的视图 action 获取了一个参数: 我们希望看到的帖子的 ID。 这个参数是通过 URL 请求传递给 action 的。 如果用户请求 /posts/view/3,那么值 ‘3’ 就被传递给 $id。

现在让我们建立一个新的 ‘view’ action 放在 /app/View/Posts/view.ctp 文件中。

1 <!-- File: /app/View/Posts/view.ctp -->
2 
3 <h1><?php echo h($post['Post']['title']); ?></h1>
4 
5 <p><small>Created: <?php echo $post['Post']['created']; ?></small></p>
6 
7 <p><?php echo h($post['Post']['body']); ?></p>

尝试输入链接 /posts/index 或者手动访问 /posts/view/1,看看工作是否正常。.

添加帖子

虽然从数据库中读出贴子并展示给我们是个不错的开始,但是我们还需要可以添加贴子。

首先,从在 PostsController 中建立 add() 方法开始:

复制代码
 1 class PostsController extends AppController {
 2     public $helpers = array('Html', 'Form', 'Session');
 3     public $components = array('Session');
 4 
 5     public function index() {
 6         $this->set('posts', $this->Post->find('all'));
 7     }
 8 
 9     public function view($id) {
10         $this->Post->id = $id;
11         $this->set('post', $this->Post->read());
12 
13     }
14 
15     public function add() {
16         if ($this->request->is('post')) {
17             $this->Post->create();
18             if ($this->Post->save($this->request->data)) {
19                 $this->Session->setFlash('Your post has been saved.');
20                 $this->redirect(array('action' => 'index'));
21             } else {
22                 $this->Session->setFlash('Unable to add your post.');
23             }
24         }
25     }
26 }
复制代码

注解

在使用 Session 的任何一个 controller 中都需要包含 SessionComponent (和SessionHelper)。如果需要,可以将它包含在 AppController 中。

add() 实现了这样几个功能:如果表单提交的数据非空,就试图使用 Post 模型保存数据。如果因为某些原因保存未成功,则渲染视图,这给了我们向用户显示数据校验或其它警告的机会。

每个 CakePHP 请求包含一个 CakeRequest 对象,它可以通过 $this->request 访问。 request 对象包含这次请求被获取的信息,并能够用于应用程序流的控制。 在本例中,我们使用 CakeRequest::is() 方法检验请求是否是以 HTTP POST 格式提交的。

当用户使用表单向应用程序提交数据(POST),其信息可以使用 $this->request->data 获取。 可以使用 pr() 或debug() 方法输出这些数据。

我们使用了 Session 组件的 SessionComponent::setFlash() 方法发送了一条信息给 session 变量,用于在中转页上显示。 在中转页的布局中我们用 SessionHelper::flash 显示和清除这个 session 变量。 该控制器的Controller::redirect 方法用于跳转到其它 URL。 参数 array('action' => 'index') 指定了跳转到 /posts URL,等于 posts 控制器的 index 方法。 你可以参考 API 中的 Router::url() 功能,它使你可以指定为不同的 Cake 函数指定一个 URL 格式。

调用 save() 方法将检查检验错误,并在出现错误时跳过保存。 我们将在后续的章节中讨论如何处理这些错误。

数据校验

Cake 在获取表单校验的单调输出方面做了大量的工作。每个人都痛恨无止境的编写表单及其验证。CakePHP 使其变得更快更容易。

想要更好的利用校验功能,就需要在视图中使用 FormHelper 助手。FormHelper 助手默认在所有视图中都可用,用法是 $this->Form。

这是我们添加的视图:

复制代码
1 <!-- File: /app/View/Posts/add.ctp -->
2 
3 <h1>Add Post</h1>
4 <?php
5 echo $this->Form->create('Post');
6 echo $this->Form->input('title');
7 echo $this->Form->input('body', array('rows' => '3'));
8 echo $this->Form->end('Save Post');
9 ?>
复制代码

在这里,我们用 FormHelper 助手生成一个 HTML 表单的起始标签。$this->Form->create() 生成的 HTML 是:

1 <form id="PostAddForm" method="post" action="/posts/add">

如果 create() 是不带参数调用的,表示创建的表单将以 POST 形式提交给同一个控制器的 add() (或者当表单中含有 id 元素时提交给 edit())动作。

$this->Form->input() 方法用来生成同名的表单元素,这个方法的第一个参数告诉 CakePHP 前后台通讯的是哪个域,第二个参数允许指定选项:本例中,是 textarea 域的行数。这里有一点自动完成的:input() 方法将基于 model 指定的域生成不同的表单元素。

$this->Form->end() 调用生成一个 submit 元素并结束表单。如果提供给 end() 方法的第一个参数是字符串,FormHelper 生成一个相应名称的 submit 域并关闭表单标签。再说一次, 助手 一节有更多的助手信息。

现在我们返回并更新 /app/View/Posts/index.ctp 视图使其包含一个新的 “Add Post” 链接。在 <table> 之前添加如下行:

1 <?php echo $this->Html->link(
2     'Add Post',
3     array('controller' => 'posts', 'action' => 'add')
4 ); ?>

你可能会奇怪:我如何通知 Cake 我的校验要求?校验规则是定义在模型中的。让我们回顾 Post 模型并稍作调整:

复制代码
 1 class Post extends AppModel {
 2     public $validate = array(
 3         'title' => array(
 4             'rule' => 'notEmpty'
 5         ),
 6         'body' => array(
 7             'rule' => 'notEmpty'
 8         )
 9     );
10 }
复制代码

$validate 数组告诉 CakePHP 在 save() 方法被调用时如何校验我们的数据。这里,我指定 title 和 body 都不能为空。CakePHP 的校验功能很强劲,带有一批预置的规则(如 信用卡号码、Email 地址等),而且可以灵活地添加自己的校验规则。可以浏览 数据校验 获取更多的相关信息。

现在已经有了校验规则,试着输入空的 title 和 body,看看它们是如何工作的。当我们使用 FormHelper 的FormHelper::input() 方法创建表单,校验的错误信息会自动显示。

编辑帖子

我们已经来到了帖子编辑这一步,现在你已经是一个 CakePHP 的高手了,所以你应该操起一个模式。编写动作,然后是视图。PostsController 的 edit() 方法类似于:

复制代码
 1 public function edit($id = null) {
 2     $this->Post->id = $id;
 3     if ($this->request->is('get')) {
 4         $this->request->data = $this->Post->read();
 5     } else {
 6         if ($this->Post->save($this->request->data)) {
 7             $this->Session->setFlash('Your post has been updated.');
 8             $this->redirect(array('action' => 'index'));
 9         } else {
10             $this->Session->setFlash('Unable to update your post.');
11         }
12     }
13 }
复制代码

这个动作首先检查用户提交的是不是 GET 请求。如果是,就找到 Post 并将其传递给视图。如果不是,就可能包含 POST 数据。我们将使用 POST 数据更新贴子记录,或者将校验的错误信息踢回并显示给用户。

edit 视图类似于:

复制代码
1 <!-- File: /app/View/Posts/edit.ctp -->
2 
3 <h1>Edit Post</h1>
4 <?php
5     echo $this->Form->create('Post', array('action' => 'edit'));
6     echo $this->Form->input('title');
7     echo $this->Form->input('body', array('rows' => '3'));
8     echo $this->Form->input('id', array('type' => 'hidden'));
9     echo $this->Form->end('Save Post');
复制代码

这个视图输出编辑表单(带有相应数据值),所有的错误校验信息也一并提供。

有件事需要注意:如果提供的数据数组中包含 ‘id’ 域,CakePHP 认为这是要修改一个模型的数据。如果没有 ‘id’ 域,cake 会认为当 save() 方法被调用时插入一条新的模型数据(参见 add 视图)。

现在可以更新 index 视图,添加一个用于编辑的链接:

复制代码
 1 <!-- File: /app/View/Posts/index.ctp  (edit links added) -->
 2 
 3 <h1>Blog posts</h1>
 4 <p><?php echo $this->Html->link("Add Post", array('action' => 'add')); ?></p>
 5 <table>
 6     <tr>
 7         <th>Id</th>
 8         <th>Title</th>
 9                 <th>Action</th>
10         <th>Created</th>
11     </tr>
12 
13 <!-- Here's where we loop through our $posts array, printing out post info -->
14 
15 <?php foreach ($posts as $post): ?>
16     <tr>
17         <td><?php echo $post['Post']['id']; ?></td>
18         <td>
19 <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id'])); ?>
20         </td>
21         <td>
22 <?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id'])); ?>
23         </td>
24         <td>
25 <?php echo $post['Post']['created']; ?>
26         </td>
27     </tr>
28 <?php endforeach; ?>
29 
30 </table>
复制代码

删除帖子

下面我们来看删除贴子的道道。在 PostsController 中添加 delete() 动作:

复制代码
1 public function delete($id) {
2     if ($this->request->is('get')) {
3         throw new MethodNotAllowedException();
4     }
5     if ($this->Post->delete($id)) {
6         $this->Session->setFlash('The post with id: ' . $id . ' has been deleted.');
7         $this->redirect(array('action' => 'index'));
8     }
9 }
复制代码

这个逻辑根据 $id 删除指定的贴子,并且使用 $this->Session->setFlash() 在用户重定向到 /posts 之后显示一条确认信息。如果用户试图用 GET 请求执行删除,我们就抛出一个异常。我们没有捕获的异常,将被 CakePHP 的异常句柄捕获并显示一个友好的错误页。有许多内置的 异常 ,能够用于指示应用程序需要生成的不同的 HTTP 错误。

因为我们仅仅执行了一些逻辑就重定向了,这个动作没有视图。但是仍然可能需要更新 index 视图,添加允许用户删除贴子的链接:

复制代码
 1 <!-- File: /app/View/Posts/index.ctp -->
 2 
 3 <h1>Blog posts</h1>
 4 <p><?php echo $this->Html->link('Add Post', array('action' => 'add')); ?></p>
 5 <table>
 6     <tr>
 7         <th>Id</th>
 8         <th>Title</th>
 9         <th>Actions</th>
10         <th>Created</th>
11     </tr>
12 
13 <!-- Here's where we loop through our $posts array, printing out post info -->
14 
15 <?php foreach ($posts as $post): ?>
16     <tr>
17         <td><?php echo $post['Post']['id']; ?></td>
18         <td>
19 <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id'])); ?>
20         </td>
21         <td>
22 <?php echo $this->Form->postLink(
23                 'Delete',
24                 array('action' => 'delete', $post['Post']['id']),
25                 array('confirm' => 'Are you sure?'));
26             ?>
27 <?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id'])); ?>
28         </td>
29         <td>
30 <?php echo $post['Post']['created']; ?>
31         </td>
32     </tr>
33 <?php endforeach; ?>
34 
35 </table>
复制代码

使用 postLink() 生成用 JavaScript 调用删除贴子请求的链接。允许使用 GET 请求删除贴子是非常危险的,web 爬虫可能会意外地删除全部内容。

注解

这个视图的代码也在删除之前使用 FormHelper 的 JavaScript 对话框提醒用户。

路由

多数情况下,CakePHP 的默认路由都能够很好地工作。对用户体验和搜索引擎兼容敏感的程序员将注意到 CakePHP 的 URL 映射到动作的方式。所以在这篇教程里我们仅仅快速的更改了一下路由。

路由技术的更多更高级的信息,请参见 路由配置 。

默认的,CakePHP 用 PagesController 回应对站点根的访问(例如 www.example.com),渲染一个叫 “home” 的视图。我们通过建立一条路由规则,用我们自己的 PostsController 来代替它。

可以在 /app/Config/routes.php 中找到路由配置。要注释掉或者删除定义默认路由的那一行。它看起来像是:

1 Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));

一行将默认的 home 页关联给 URL ‘/’。我们想要用我们自己的控制器关联它,所以用如下行替换这一行:

1 Router::connect('/', array('controller' => 'posts', 'action' => 'index'));

这将把 PostsController 的 index() 动作关联给 URL ‘/’。

注解

CakePHP 还支持 ‘逆向路由’ ——如果通过``array(‘controller’ => ‘posts’, ‘action’ => ‘index’)`` 传递给期望得到数组的函数来定义如上路由,那么结果将是 ‘/’。这意味着总是用数组通过路由去定义要去的 URL 是个好主意,并能确保总是会指向同一个位置。

结语

创建应用程序这条路,将使你赢得超出以往的狂热幻想的和平、光荣、爱和金钱。容易,不容易?记住,这个教程只是一个基础。CakePHP 提供了更多的特性和更灵活的方式,简单起见,我们不希望这个教程覆盖那么多。使用手册的剩余部分作为构建富于特性的应用的指南。

现在已经建立了一个基于真实内容的基本的 Cake 应用程序。阅读 Cookbook 和 API 的剩余内容,开始自己的项目吧。

如果需要帮助,到 #cakephp 来看我们。欢迎来到 CakePHP!

建议后续阅读:

这些都是学习CakePHP的人将来通常要研究的共同任务:

  1. 布局: 自定义 web 站点的布局
  2. 元素 :包含和重用视图片断
  3. 脚手架: 创建代码前的原型
  4. 使用 Bake 生成代码 使用 Bake 生成基本的 CRUD 代码
  5. 简单授权验证和授权应用程序: 用户验证和授权教程

延伸阅读

  • 一个典型的 CakePHP 请求
  • CakePHP 约定
    • 控制器约定
      • 关于控制器命名的思考
    • 文件名和类名约定
    • 模型和数据库约定
    • 视图约定
  • CakePHP 的文件夹结构
    • app 文件夹
  • CakePHP 的结构
    • 应用程序扩展
    • 控制器扩展 (“组件”)
    • 模型扩展 (“行为”)
    • 视图扩展 (“助手”)

你可能感兴趣的:(CakePHP 2.x CookBook 中文版 第三章 入门)