2009年12月22日 星期二

CakePHP教學 on OSX(六)Todo應用程式練習:(2)自動產生程式碼 Bake All 一次烤熟!

雖然翻了幾本CakePHP跟RoR的書,但都還沒有全部看完。不過就我目前的了解,兩者建立資料庫的方式有點不同。RoR可以透過建立migrate檔案,記錄歷次資料庫架構(schema)設計上的改變,作為版本遷移的依據。RoR並且可以透過migrate檔案,產生不同的資料庫系統建立資料表所需的SQL程式碼,並自動產生資料庫檔案。這樣一來讓RoR的開發與資料庫的設計,不會遷就特定的資料庫系統而必須大幅修改程式碼。就這點來說,RoR可說是非常先進的設計。

CakePHP卻是要先用phpMyAdmin或其他的工具,在資料庫系統中先構建出完整的資料庫檔案,然後才能透過schema腳本從既有的資料庫備份出SQL檔案,作為資料庫架構的記錄與遷移的依據。或是先用SQL語言寫好資料庫的架構,再透過schema腳本將資料庫製作出來。方法上也許沒有RoR先進,但是我想一般的PHP開發者,應該都很熟悉這樣的開發方式。而且只要資料庫架構設計的夠好夠正確,透過bake腳本自動產生程式碼,甚至比RoR一步步地架構 scafford 還要迅速哦!這篇還是根據“Beginning CakePHP: From Novice to Professional”這一本書的第一個“Todo”範例加以修改。

用phpMyAdmin建立 todo 資料庫、帳號與密碼
  1. 打開MAMP視窗(基本上開發PHP過程中,MAMP應該都要一直開著),按一下“Open Start Page”按鈕:
  2. 按一下上方的“phpMyAdmin”標籤:
  3. 基本上MAMP是開發用的通常都不會拿來當正式的伺服器,所以root使用者我也沒有去更動密碼(有嘗試變更過但會出錯),所以MySQL的root安全性問題,這裡先跳過。phpMyAdmin的預設介面語言是英文,如果不習慣,可以在下方的“Interface”下的“Language”選單,選擇“中文 Chinese traditional”:
  4. 接下來要製作todo帳號跟資料庫。如果不是在phpMyAdmin的首頁,先點一下左上角的“小房子”圖像跳到首頁,後點一下上方的“權限”標簽,再點下方的“新增使用者”的超連結:
  5. 進入“新增使用者”的頁面,在“登入資訊”區內,“使用者名稱”欄位輸入:todo,主機選“本地(localhost)”,“密碼”跟“確認密碼”輸入相同的密碼值(之前bake腳本時設定的是:todo2009),不要按產生密碼按鈕。下方的“Database for user”區,請勾選第二項“Create database with same name and grant all privileges”,這樣就會自動產生一個同名的todo資料庫,並給同名的使用者與完全的存取權限。為了安全起見,“整體權限”內容請勿勾選。確認設定一切無誤後,請按右下方的“執行”按鈕:
  6. 指令執行成功的話,todo帳號跟同名的資料庫就產生了。點一下左側邊欄的“todo”連結,進入todo資料庫:
  7. 進入進入todo資料庫後,按一下上方的“SQL”標籤,在下方的欄位中貼上以下的SQL程式碼,然後按下執行:
    CREATE TABLE `items` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) CHARACTER SET utf8 NOT NULL,
    `completed` tinyint(1) NOT NULL,
    `created` datetime DEFAULT NULL,
    `modified` datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
  8. 如果SQL程式沒有問題,就會看到items資料表出現在左側邊欄的todo資料庫下方:
  9. 這裡的資料表設計跟“書上”的範例有點不同。“書上”的範例是用一個“date”欄位來儲存時間,但是編寫model的驗證程式時跳過去。但是如果用書上的SQL產生的資料庫導入bake自動地產生程式,測試時發現一直無論“date”欄位如何選擇,都會出現一個“field empty”的驗證錯誤。所以這裡改用兩個CakePHP預設的“魔術欄位”:created”跟modified”兩個欄位,並設定成“datetime”格式,預設值是“NULL”。這樣一來CakePHP會自動地用created”儲存資料產生的時間,並用modified”儲存最後修改的時間,完全不用寫任何一行程式碼!!
增加bake all指令
CakePHP的bake腳本有一個超好用的參數“all”,一次就可以根據資料庫內所有的資料表,建立所有相關的model/controller/view的基本CRUD程式,甚至能自動建立資料表之間的關連性。所以這裡要把之前的bake外部指令修改一下,加入all參數:
  1. 從Aptana的“Run”選單下選擇“External Tools Configurations...”:
  2. 在左側邊欄上的bake指令上按右鍵,選擇“Duplicate”複製一個副本:
  3. 將新的外部指令改名為bake all,將在下方的“arguments”欄位參數改為 bake all ,然後按一下右下方的“Apply”按鈕儲存後,按“Close”按鈕關閉(暫時不要立即執行):
  4. 雖然bake all已經做好,但“Run”選單下卻看不到。要在“Run”選單下顯示bake all指令,請選擇“Organize Favorites...”:
  5. 出現“Organize Exertnal Tool Favorites”視窗,請按“Add”按鈕:

  6. 出現“Add Exertnal Tool Favorites”視窗,勾選要增加的兩個指令,或按“Select All”之後,按“OK”關閉視窗:
  7. 回到“Organize Exertnal Tool Favorites”視窗,請按“OK”按鈕關閉。以後就可以在Run選單裡看到bake跟bake all兩個外部指令:

用bake all自動建立基本的CRUD應用程式
  1. 外部指令bake all作好後,就可以套用在專案上。請先點一下左邊“PHP Explorer”視窗裡的“todo”專案圖示,然後從“Run”選單下選取“bake all”指令:
  2. Aptana會在下方的“Console”視窗顯示“bake all”的輸出結果。“bake all”會依照/config/database.php所設定的連線資料,從資料庫裡截取每一個資料表,依序循問要不要建立相關的model程式。接下來的操作都要在“Console”視窗裡輸入指令:

  3. 因為todo資料庫裡只有一個“items”資料表,所以這裡也只顯示一個項目,請輸入 1 後按下Enter繼續:
    Welcome to CakePHP v1.2.4.8284 Console
    ---------------------------------------------------------------
    App : todo
    Path: /Applications/MAMP/htdocs/todo
    ---------------------------------------------------------------
    ---------------------------------------------------------------
    Bake All
    ---------------------------------------------------------------
    Possible Models based on your current database:
    1. Item
    Enter a number from the list above, type in the name of another model, or 'q' to exit
    [q] > 1
  4. 接下來bake指令就開始自動產生所有的基本程式。過程中好像會發生時區設定的小問題,但不影響程式的產生。然後會出現製作檔案的提示,你可以看看bake all為你製作了哪些檔案。完成後,會顯示“Bake all complete”:
    One moment while the associations are detected.

    Baking model class for Item...

    Creating file /Applications/MAMP/htdocs/todo/models/item.php
    Wrote /Applications/MAMP/htdocs/todo/models/item.php
    Item Model was baked.

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Chongqing' for 'CST/8.0/no DST' instead in /Applications/MAMP/htdocs/cake_1_2/cake/console/libs/tasks/model.php on line 879

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Chongqing' for 'CST/8.0/no DST' instead in /Applications/MAMP/htdocs/cake_1_2/cake/console/libs/tasks/model.php on line 879

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Chongqing' for 'CST/8.0/no DST' instead in /Applications/MAMP/htdocs/cake_1_2/cake/console/libs/tasks/model.php on line 930

    Baking test fixture for Item...

    Creating file /Applications/MAMP/htdocs/todo/tests/fixtures/item_fixture.php
    Wrote /Applications/MAMP/htdocs/todo/tests/fixtures/item_fixture.php

    Baking unit test for Item...

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Chongqing' for 'CST/8.0/no DST' instead in /Applications/MAMP/htdocs/cake_1_2/cake/console/libs/tasks/model.php on line 736

    Creating file /Applications/MAMP/htdocs/todo/tests/cases/models/item.test.php
    Wrote /Applications/MAMP/htdocs/todo/tests/cases/models/item.test.php

    Creating file /Applications/MAMP/htdocs/todo/controllers/items_controller.php
    Wrote /Applications/MAMP/htdocs/todo/controllers/items_controller.php
    Item Controller was baked.

    Baking unit test for Items...

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Chongqing' for 'CST/8.0/no DST' instead in /Applications/MAMP/htdocs/cake_1_2/cake/console/libs/tasks/controller.php on line 487

    Creating file /Applications/MAMP/htdocs/todo/tests/cases/controllers/items_controller.test.php
    Wrote /Applications/MAMP/htdocs/todo/tests/cases/controllers/items_controller.test.php

    Creating file /Applications/MAMP/htdocs/todo/views/items/index.ctp
    Wrote /Applications/MAMP/htdocs/todo/views/items/index.ctp

    Creating file /Applications/MAMP/htdocs/todo/views/items/view.ctp
    Wrote /Applications/MAMP/htdocs/todo/views/items/view.ctp

    Creating file /Applications/MAMP/htdocs/todo/views/items/add.ctp
    Wrote /Applications/MAMP/htdocs/todo/views/items/add.ctp

    Creating file /Applications/MAMP/htdocs/todo/views/items/edit.ctp
    Wrote /Applications/MAMP/htdocs/todo/views/items/edit.ctp
    Bake All complete
  5. 不過bake all完成後,還會繼續詢問是否產生其他model程式。如果再輸入一次選項 1 的話,bake all腳本會重新再製作一次所有的程式,而且檔案夾裡如果已經有重複的程式檔案的話,還會詢問你是否要“覆寫”?如果不要再重新產生或製作其他的model,請輸入 q 後按 Enter 結束bake all腳本:
    ---------------------------------------------------------------
    Bake All
    ---------------------------------------------------------------
    Possible Models based on your current database:
    1. Item
    Enter a number from the list above, type in the name of another model, or 'q' to exit
    [q] > q
    Exit
  6. 請注意,Aptana的“PHP Explorer”視窗並不會立即顯示剛剛bake all所產生的所有新檔案。請在 todo 專案圖像上按右鍵,選擇“Refresh”後,才能看到剛剛新產生的程式檔。
到這裡我們已經用CakePHP產生一個基本的俱備資料庫CRUD功能的應用程式,但其實只改了database.php裡的一行參數加上括號而已,大部份的時間都是在設定Aptana的功能而已,一個完整的應用程式就給烤出來了產生了。接下來請在瀏覽器裡輸入 http://localhost/todo/items 這個網址,品嚐看看一口CakePHP為我們烤出來的todo蛋糕滋味如何?

沒有留言:

張貼留言