11.16
雖然我最近都在寫 JAVA ,但我還是想撥空把前陣子寫 CakePHP 的心得和大家分享,而以下文章則針對 CakePHP 說明。
MVC 是 Model View Controller 的縮寫,這是一種設計模式,方便把頁面和商業邏輯分開來處理。而 CakePHP 則是使用 PHP 實做這種設計模式的一套 Framework 。在 CakePHP 中, Model 代表的是資料庫、 Controller 代表的是商業邏輯的判斷處理,View 代表的則是使用者呈現的頁面。另外 CakePHP 實做了一個很重要的觀念叫做 ORM (Object-Relational Mapping),在 CakePHP 中 ORM 把每一個資料庫宣告成一個類別 (Class) ,接著我們在透過 Controller 來處理資料庫的資料,避免直接使用 SQL 語言進行查詢,增加程式的彈性和可維護性。
建議在看這篇文章之前,先把 CakePHP 使用手冊 讀一遍,最好的狀況是能夠跟著教學實做一遍。因為跟著做過一次之後,會發現其實並不那麼困難,以下的例子是仿照 tutorial 寫成的,當然還有依據實際情況修改一些東西。我會陸續貼出來。
在學這套 Framework 之前,我們必須先大略瞭解 CakePHP 的目錄結構,在安裝之後,一開始我們會看到三個目錄:
/app - 所有東西都放這邊! /cake - CakePHP 的函式庫,不用去動 /venders - 3rd party 的東西 index.php - 改寫網址用 .htaccess - 改寫網址用,Apache 必須掛載 mod_rewrite
而這系列的文章,都會專注在 /app 的這個資料夾下面。
如果對 MVC 架構有興趣,請仔細拜讀這兩篇文章:
Web MVC – Oliver Steele
進階 php 程式設計 介紹 MVC 與 Cakephp
而 CakePHP 的流程是這樣的:

在 CakePHP 的環境中,程式對網址規則有嚴格的要求,例如:
http://example.com/posts/index/
就代表他用的 Controller 叫做 Posts_Controller ,而 index 則是 Controller 裡面的一個 method 。
http://example.com/posts/index/30
則表示把 30 這個參數用 GET Method 傳入 index 這個 method 裡面。
我實了一個 Valerossi.net 的網站,裡面放賽車手 Rossi 的自傳,我把實做的過程一步一步記錄下來和大家分享,也希望對 CakePHP 有興趣的人,可以不吝指教。
先修改連線設定檔,如果資料庫是 utf8 編碼,請最後加入鍵名 encoding 和鍵值 utf8:
|
1 2 3 4 5 6 7 8 9 10 |
/* /app/config/database.php */ var $default = array('driver' => 'mysql', 'connect' => 'mysql_connect', 'host' => 'localhost', 'login' => 'NAME', 'password' => 'PASSWORD', 'database' => 'cake', 'prefix' => '', 'encoding' => 'utf8'); // 請注意這一行! |
在 app/Model/post.php 裡面宣告一個類別,代表要操作的資料庫
|
1 2 3 4 5 6 7 8 |
<?php class Post extends AppModel { var $name = 'Post'; // var $useTable = 'articles'; 也可以這樣去指定資料表 } ?> |
這代表了新增一個 Model ,我們採用預設的命名規則,資料庫的名稱叫做 posts (複數)。當然,我們也可以不用預設命名規則,如上所示。
接下來建立 app/controllers/posts_controller.php 當作 Controller 。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php class PostsController extends AppController { var $name = 'Posts'; function index() { $this->set('posts', $this->Post->findAll($conditions = null, $fields = "", $order = 'ID ASC', $limit = null, $page = 1, $recursive = null)); } // 這邊要依照 ID 排序,$condition 代表的是 SQL 的 WHERE 條件 function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } // 這是閱讀單篇文章用的 } ?> |
Controller 裡面的$this->set() 就是用來把變數「傳遞」到 view 中,例如
|
1 2 3 4 |
//在某個 Controller 裡面的 method $hello = "Hello World" $this->set('post', $hello); |
這個動作可以把 Hello World 這個字串傳到 view ,變成 $post 變數,當在 view 中執行 echo $post 的時候,會印出 Hello World 。
至於 view 的寫法非常簡單,
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<h1>文章列表</h1> <table> <tr> <th>標題</th><th>時間</th><th>譯者</th> </tr> <?php foreach ($posts as $post): ?> <tr> <td><?php echo $html->link($post['Post']['post_title'], "/posts/view/".$post['Post']['ID']); ?></td> <td><?php echo $post['Post']['post_date']; ?></td> <td><?php echo $post['Post']['post_author']; ?></td> <td></td> </tr> <?php endforeach; ?> </table> |
這樣就是一個 view 。而 view 擺放的路徑則因 Controller 而定, view 的檔名則隨著 Controller 的 Method 而定,例如 Posts::index() 的 view 就是 /views/posts/index.thtml ,而 Posts::view() 的 view 則是 /view/posts/view.thtml。




“資料庫的名稱叫做 posts (複數)”…
是資料表 table 嗎?
有個小問題(我是在跟你的這個 post 學起 Cake 來):
當我指向 http://127.0.0.1/cake_app/post/index, Cake 給我一個 err msg: “Missing Database Table”
那我要用 bake (scaffold? )去替我產生 table 嗎?
對,是資料表,很抱歉,我打錯了。另外我資料庫和資料表的 scheme 都是自己想、自己建的。
我最近都在寫 Jasper 報表,所以很少玩 CakePHP ,也沒什麼新的進度,等之後放假或是有空,再補充文章上來,其實我覺得有很多地方值得討論,只是時間不夠用
原來比起我初次接觸 CakePHP 已經快要兩年了。Roga 你還有用這套 framework 嗎?
我曾為了做一個(私人的) project ,試用了點 Cake ,再去學了點 RoR。結果……後來還是用起 Cake 來了(RoR 很好,可是 hosting 還是個大問題吧!)。
最近想寫一個 book library (給自己用的),所以又找來 Cake 了
建議你用 CodeIgniter ,我沒有用 Cake 。反倒是用 CodeIgniter 這套我已經寫了好幾個網站
[...] roga's blog » Web MVC – CakePHP 教學實做 – 簡介 簡單範例實作CakePHP (tags: mvc php cakephp framework) [...]