雖然我最近都在寫 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 11 |
/* /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 9 |
<?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 23 |
<?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 5 |
//在某個 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 16 |
<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。
Hello there, You have done a fantastic job. I’ll certainly
digg it and personally suggest to my friends. I am sure they’ll be benefited from this site.
My website :: beauty care; Sherry,
原來比起我初次接觸 CakePHP 已經快要兩年了。Roga 你還有用這套 framework 嗎?
我曾為了做一個(私人的) project ,試用了點 Cake ,再去學了點 RoR。結果……後來還是用起 Cake 來了(RoR 很好,可是 hosting 還是個大問題吧!)。
最近想寫一個 book library (給自己用的),所以又找來 Cake 了 🙂
建議你用 CodeIgniter ,我沒有用 Cake 。反倒是用 CodeIgniter 這套我已經寫了好幾個網站 😀
對,是資料表,很抱歉,我打錯了。另外我資料庫和資料表的 scheme 都是自己想、自己建的。
我最近都在寫 Jasper 報表,所以很少玩 CakePHP ,也沒什麼新的進度,等之後放假或是有空,再補充文章上來,其實我覺得有很多地方值得討論,只是時間不夠用
有個小問題(我是在跟你的這個 post 學起 Cake 來):
當我指向 http://127.0.0.1/cake_app/post/index, Cake 給我一個 err msg: “Missing Database Table”
那我要用 bake (scaffold? )去替我產生 table 嗎?
“資料庫的名稱叫做 posts (複數)”…
是資料表 table 嗎? 😉