21條CakePHP編程技巧

jopen 10年前發布 | 18K 次閱讀 CakePHP Web框架

快速創建靜態頁面

我想建立幾個頁面,它們僅包含靜態數據,使用默認layout,不需要任何model。 最初我試圖創建一個controller并為每個靜態頁面定義一個action。 但這種方法很笨拙,也不適合快速創建靜態頁面。
 
實際上只要使用pages controller就可以做到——只要在 views/pages 文件夾下創建一個 view,就可以通過 /pages 來訪問。例如,我創建了 /views/pages/matt.thtml , 就可以通過 http://www.example.com/pages/matt來訪問。
 
改變靜態頁面的標題

使用pages controller時如果想改變頁面標題,只需在view中加入以下代碼:
 <? $this->pageTitle = 'Title of your page.'; ?>
在靜態頁面中向layout發送數據

如果需要向layout傳遞數據(例如表示導航欄中哪個部分應該高亮顯示的變量), 可以在view中添加下面的代碼:
 <? $this->_viewVars['somedata'] = array('some','data'); ?>
這個數組就可以在layout中通過$somedata來訪問。
 
快速創建后臺管理

如果你需要創建后臺管理程序,并且希望所有管理action都位于某個特定文件夾下, 那么打開 config/core.php 并將下面這一行的注釋去掉:
 define('CAKE_ADMIN', 'admin');
這樣所有以"admin_"開頭的action都可以通過 /admin/yourcontroller/youraction 來訪問。 例如,如果在posts controller中創建了名為"admin_add"的action, 那么可以通過 www.example.com/admin/posts/add 訪問這個action。 這樣就可以方便地為admin目錄設置密碼以避免他人隨意訪問。
 
查看后臺執行的SQL語句

只需改變config/core.php中的DEBUG常量,即可看到后臺執行的SQL語句。 0為產品級,1為開發級,2為完整調試SQL,3為完整調試SQL并顯示對象數據。 我通常將DEBUG設置為2,這樣每頁的底部會顯示出一個包含SQL調試信息的表格。
 
如果頁面底部添加的表格會破壞頁面布局(特別是使用Ajax獲取頁面并顯示到頁面中間而不是底部時), 你可以在CSS中添加以下代碼以隱藏調試信息:
 #cakeSqlLog { display: none; }
這樣既能保持頁面布局,又可以通過查看源代碼來看到調試信息。 當然最后發布網站時別忘了將調試級別改回0。
 
獲取豐富的開發文檔

別總是盯著手冊。wiki和API也是無價之寶。wiki中的開發指南十分有用,而API文檔初看起來比較難, 但你很快就會發現這里的信息對你創建CakePHP網站十分重要。`
 
使用bake.php

Bake是個命令行PHP腳本,可以根據數據庫自動生成model、controller和view。 在開發的最初階段,我強烈推薦使用scaffolding讓你的原型程序跑起來。 但如果你清楚地知道scaffolding不合適,我推薦你使用bake。 bake會生成所有的文件并保存到磁盤上,以便你隨意修改。 這樣能節省創建關聯、view、基本的CRUD crollder操作的重復工作。
 
(譯者注:CRUD - Create, Read, Update, Delete,數據庫應用的四種基本操作,即"增刪查改"。)
 
bake很方便。你只需在數據庫中建立一個表,然后到 /cake/scripts/ 目錄下執行 php bake.php 即可。
 
如果你通過交互方式來運行bake,它會分幾步提示你創建model、controller和view。 創建結束之后,我通常會閱讀所有生成的代碼并做必要的修改。
 
發布程序時注意權限

有一次我在發布程序時,將整個cake目錄打包然后用scp上傳到了服務器上。 只要一關閉調試信息,就會出現錯誤——數據庫調用無法返回任何數據。 我一籌莫展,因為我必須通過調試信息才能調試問題。 后來有人告訴我,/app/tmp應當對apache可寫。將權限改為777之后問題就解決了。
 
復雜model驗證

我需要進行更復雜的驗證,而不僅僅是驗證輸入框非空或者符合某個正則表達式這樣的簡單驗證。 例如,我要驗證用戶注冊時使用的郵件地址是否已被使用。在wiki中我找到了這篇 關于高級驗證的文章 , 其中提到了一些十分有用的高級驗證方法。
 
記錄錯誤日志
$this->log('Something broke');
這樣可以將錯誤記錄到 /tmp/logs/ 中(我最初以為會記錄到apache的錯誤日志中)。
 
讓controller使用其他model

如果你的controller需要調用來自不同model的數據,只要在controller開頭使用如下代碼:
 class yourController extends AppController {
  var $uses = array('Post','User');
}
這樣controller就能訪問Post和User model了。
 
創建不使用數據庫表的model

我需要創建一個不使用任何表的model。例如,我想通過$validate數組方便底驗證輸入數據, 保持model邏輯的正確性。但創建model時對應的表不存在,CakePHP就會報錯。 通過在model中加入以下代碼可以解決這個問題:
 var $useTable = false;
你也可以通過這種方法改變model對應的表名。
 var $useTable = 'some_table';
重定向之后記得exit()

對于有經驗的人來說這應當是理所當然的事兒,調用 $this->redirect() 之后,剩下的代碼如果不想運行 要exit()。我也這樣做,但以前曾經認為 $this->redirect() 會為我調用exit(實際上不會)。
 
高級model函數

翻翻API就能發現很多你不知道的非常有用的函數。 我強烈推薦至少閱讀一遍 Model 類的參考手冊 。 下面是以前我沒注意到的幾個重要函數:
 ?generateList()- 主要用于生成選擇框(<SELECT>)所需的數據
 ?query()- 自己寫SQL語句來查詢
 ?findCount()- 返回滿足指定條件的行數
 ?hasAny()- 當有記錄滿足條件時返回真
 
再次強烈推薦閱讀整個model類參考 ,你會為你學到的東西贊嘆的。
 
如何正確插入多行

我需要遍歷一個列表,并將其中的每個元素都插入到數據庫中。 我發現如果在一次插入完成后立即進行下一次插入, 那么第二次插入的內容完全不會被插入,而是會被更新到第一次插入的行中。 例如:
 $items = array('Item 1','Item 2','Item 3');
foreach ($items as $item) {
  $this->Post->save(array('Post' => array('title' => $item)));

這段代碼將在posts表中插入僅一行:“Item 3”。 CakePHP首先插入“Item 1”,但馬上將其更新為“Item 2”, 再更新為“Item 3”,因為$this->Post->id保存的是上一次插入成功的行的id。 通常這個特性很有用,但在這個例子中反而幫了倒忙。 其實只要在每次插入之后設置 $this->Post->id = false 就可以解決這個問題。
 
更新:有人發郵件告訴我,正確的做法是調用create()初始化model,再set/save新數據。
 
在controller函數之前或之后插入邏輯

假設你需要在controller渲染的每個view中都設置一個顏色數組, 但你不希望在每個action中都定義它。可以通過 beforeRender() 回調函數來實現:
 function beforeRender() {
  $this->set('colors',array('red','blue','green');
}
這樣該controller渲染的所有view都可以訪問$colors變量。 beforeRender() 函數在controller邏輯結束后、view被渲染之前執行。同樣, beforeFilter() 和afterFilter() 函數會在每個controller action執行的前后執行。 更多信息請閱讀手冊的models一節 。
 
為CakePHP添加所見即所得編輯器

這里有一篇非常好的教程 教你如何在 CakePHP中使用TinyMCE。基本上你只需在頁面上鏈接tiny_mce.js文件,然后添加一些初始化代碼以設置 將哪個textarea變成TinyMCE編輯器即可。
 
自定義HABTM關系的SQL語句

我曾試圖在自定義的SQL語句上定義一個HABTM關系(has-and-belongs-to-many),卻遇到了問題。 根據本文撰稿時的文檔,應當先在自己的model中設置finderSql,但從CakePHP的源代碼來看, 應該設置finderQuery 。這只是文檔中的一個小問題,但指出問題卻能為他人節約時間。 Trac ticket在這里 。
 
發送郵件

我在wiki中找到兩篇教程:發送郵件 和 通過PHPMailer發送郵件 。 強烈推薦后者,通過PHPMailer發送郵件更安全,而且不需要自己處理郵件頭,減少許多麻煩。
 
自定義Helper生成的HTML

我需要修改調用$html->selectTag()時生成的<option>,使其生成“請選擇”選項來代替默認的空白選項。 我也希望單選按鈕能帶有標簽,這樣用戶就無需精確地點擊單選按鈕本身,而只需單擊到關聯的文字上即可。
 
建立 /app/config/tags.ini.php,然后添加以下的內容:
 ; Tag template for a input type='radio' tag.
radio = "<input type="radio" name="data[%s][%s]" id="%s" %s /><label for="%3$s">%s</label>"

; Tag template for an empty select option tag.
selectempty = "<option value="" %s>-- Please Select --</option>"
你可以從/cake/config/tags.ini.php中獲得完整的標簽列表。但我不建議修改該文件, 否則升級CakePHP時可能會讓你的修改丟失。
 
自定義404頁面

如果你需要自定義404頁面,只需創建 /app/views/errors/error404.thtml。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!