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 的文件夾結構 一節。

建立博客數據庫

接着,設置博客的基本數據庫。如果你還不曾這么做,建立一個為本教程所用的空數據庫,名稱任選。現在,建立一個單表用來存儲博客貼子。我們也拋出幾個貼子用於測試。在數據庫上執行如下語句:

 1 /* First, create our posts table: */
 2 CREATE TABLE posts (
 3     id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
 4     title VARCHAR(50),
 5     body TEXT,
 6     created DATETIME DEFAULT NULL,
 7     modified DATETIME DEFAULT NULL
 8 );
 9 
10 /* Then insert some posts for testing: */
11 INSERT INTO posts (title,body,created)
12     VALUES ('The title', 'This is the post body.', NOW());
13 INSERT INTO posts (title,body,created)
14     VALUES ('A title once again', 'And the post body follows.', NOW());
15 INSERT INTO posts (title,body,created)
16     VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());

表名和列名並非隨意指定的。如果遵循 Cake 的數據庫命名規則和 Cake 類命名規則(兩者的要點都在 CakePHP 約定 一節),能夠得到額外的好處:附送的功能並且無需配置。Cake 足夠靈活以適應糟糕的遺留數據庫結構,但是遵循規則會節省很多時間。

更多的信息參見 CakePHP 約定 一節,簡單點說,只要把表命名為“posts“就能自動與 Post 模塊掛靠在一起,而 modified 和 created 列則會被 Cake 自動管理。

Cake 數據庫配置

步步高升:讓我們告訴 Cake 數據庫在哪兒以及如何連接它。對於多數情況,這是唯一的配置。

/app/Config/database.php.default 是 CakePHP 數據庫配置文件的一個副本,在同一目錄中復制這個文件,命名為database.php 。

這個配置文件非常簡單:只要用實際的值替換數組 $default 的值。下面是一個完整的配置數組的示例:

 1 public $default = array(
 2     'datasource' => 'Database/Mysql',
 3     'persistent' => false,
 4     'host' => 'localhost',
 5     'port' => '',
 6     'login' => 'cakeBlog',
 7     'password' => 'c4k3-rUl3Z',
 8     'database' => 'cake_blog_tutorial',
 9     'schema' => '',
10     'prefix' => '',
11     'encoding' => ''
12 );

保存了新的 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 文件夾)。使用漂亮的表格格式化數據,其視圖類似於:

 1 <!-- File: /app/View/Posts/index.ctp -->
 2 
 3 <h1>Blog posts</h1>
 4 <table>
 5     <tr>
 6         <th>Id</th>
 7         <th>Title</th>
 8         <th>Created</th>
 9     </tr>
10 
11     <!-- Here is where we loop through our $posts array, printing out post info -->
12 
13 <?php foreach ($posts as $post): ?>
14     <tr>
15         <td><?php echo $post['Post']['id']; ?></td>
16         <td>
17 <?php echo $this->Html->link($post['Post']['title'],
18 array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
19         </td>
20         <td><?php echo $post['Post']['created']; ?></td>
21     </tr>
22 <?php endforeach; ?>
23 <?php unset($post); ?>
24 </table>

希望這看起來挺簡單。

你可能已經注意到例子中所用的那個調用 $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 的結構
    • 應用程序擴展
    • 控制器擴展 (“組件”)
    • 模型擴展 (“行為”)
    • 視圖擴展 (“助手”)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM