使用 CodeIgniter 快速簡單地創建 MVC 應用程序
Thomas Myer, 作者、顧問和 Web 開發人員, Triple Dog Dare Media
2008 年 9 月 16 日
創建 CodeIgniter 應用程序要比您想像中的容易。我將引導您創建第一個項目:一個帶有聯系人表單的簡單 Web 頁面。<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
如果您是一位 PHP 開發人員,在使用 PHP 編程語言時不難發現:大型項目可能會變得復雜。
這并非 PHP 的缺點。是的,這種語言提供了豐富的特性,而且具有足夠理想的彈性,可區分程序員之間的工作成果。在這種意義上,PHP 類似于 Perl,這是一些人喜歡它(而其他人鄙視它)的原因之一。任何曾經查看過遺留 PHP 項目的有經驗的 PHP 開發人員都可以輕松判斷出不同開發人員在項目不同階段的工作 — 就像您是一位考古學家,正在凝視著深深的墓穴,見證著不同文化在各自時代的發展。
不管涉及了什么樣式或使用了什么方法,超過幾千行代碼的 PHP 項目很容易在倉促之中變得凌亂不堪。這主要是因為它們在結構上不一致。一些程序員創建類來組織其工作,但似乎沒有任何兩個程序員對于如何編寫類具有相同的看法。其他程序員構建大量充滿函數的包含文件。還有其他人使用巨大、獨立的庫,比如 PEAR。
在幾年前,PHP 一直缺乏一個良好的、功能完善的模型-視圖-控制器(Model-View-Controller,MVC)框架。MVC 框架允許程序員將其代碼組織為三個不同的功能區:
- 模型 包含與您的數據庫和其他數據結構相關的所有代碼。如果您具有一個名為 pages 的表,則您具有一個模型,其中具有用于從表中選擇、創建、更新和刪除記錄的函數。
- 視圖 包含所有顯示和 UI 元素 — JavaScript 代碼、Cascading Style Sheets (CSS)、HTML 甚至 PHP。
-
控制器
將一切聯系在一起。控制器中的每個函數表示一個目的地或路線。如果您具有一個名為 /about 的目的地,則控制器將具有一個名為
about()
的函數。
如果以前沒有使用過 MVC 框架,上述三點無法體現出這種組織模式的強大之處。一旦您開始用 MVC 思考,您對 PHP 開發的觀點和態度將發生顯著變化。
例如,不是在項目的每個可用角落中都塞入數據庫查詢代碼,而是將一切都組織到模型中。為了從數據庫表中選擇頁面,可以使用頁面模型中的函數。
同樣地,如果您需要更新特定頁面的外觀,可以使用視圖,而不用與控制器打交道。與此類似,控制器是為您的應用程序添加目標和其他控制代碼的位置;不必在模型中放入任何此類東西。
無論使用哪種 MVC 框架,在一天之內,您就會意識到您具有一個容易記住、可按需擴展的系統。如果客戶在下周需要更改,沒問題 — 您可以搞定。如果第二年有什么請求,同樣如此。
在所有 MVC 框架中,最著名的莫過于 Ruby on Rails。多年以前,它席卷 Web 開發領域,滿足了所有人的想像。它并非純粹的 MVC 框架,而是一種約定優于配置的 MVC 框架。
約定優于配置 意味著使用 Rails 時,您需要設置一些關鍵配置項(例如數據庫的位置、特定用戶名和路徑),其他配置均由智能默認設置處理,您可在隨后修改,也可不加修改。
結果不僅僅能得到組織良好的代碼,而且還有速度極快、易于使用的 Web 開發環境。這都是 PHP 世界的夢想。經過一兩年之后,許多類似于 Rails 的工具紛紛出現:CakePHP、Symfony 等等。
最終,EllisLab 的工作人員發布了 CodeIgniter。許多企業嘗試體驗過所有 PHP MVC 框架之后,CodeIgniter 都成為贏家,主要是由于它為組織提供了足夠的自由支持,允許開發人員更迅速地工作。
自由意味著使用 CodeIgniter 時,您不必以某種方式命名數據庫表,也不必根據表命名模型。這使 CodeIgniter 成為重構遺留 PHP 應用程序的理想選擇,在此類遺留應用程序中,可能存在需要移植的所有奇怪的結構。
CodeIgniter 不需要大量代碼(1.6.2 版本僅為 2.8 MB,其中的 1.3 MB 是可以刪除的用戶文檔),也不會要求您插入類似于 PEAR 的龐大的庫。它在 PHP 4 和 PHP 5 中表現同樣良好,允許您創建可移植的應用程序。最后,您不必使用模板引擎來創建視圖 — 只需沿用舊式的 HTML 和 PHP 即可。
至此,我們已經提供了足夠的介紹,下面來構建一個簡單的項目,看看它的效果。
在構建任何 CodeIgniter 新項目時,第一步都是下載最新軟件包(在本文撰寫時,最新軟件包是 1.6.2,請參見 參考資料 小節)。下載壓縮存檔文件(.zip)并解壓縮之后,您就獲得了一個 codeigniter_ <version_number> 文件夾,其中包括開始創建所必須的一切內容。
在進行一組必需的輕微的配置更改之前,本節將為您簡單介紹 CodeIgniter,使您熟悉它的基礎知識。
打開 CodeIgniter 文件夾時,您會看到一個名為 system 的文件夾。所有 CodeIgniter 代碼都將存放在這里。在此文件夾內還有一些文件夾,其中有一個名為 application:您要處理的 99.999% 的文件都將位于此文件夾內。該文件夾的命名十分貼切,因為它包含您的應用程序及其所有組成部分 — system 文件夾的其他部分包括 CodeIgniter 核心代碼和其他不應混淆的文件。
application 文件夾下又分為多個文件夾(參見 圖 1 )。大多數文件夾易于理解。模型存放在 models 文件夾中、視圖存放在 views 文件夾中、控制器存放在 controllers 文件夾中,依此類推。還有一些文件夾用于存儲 CodeIgniter 幫助程序和庫的本地擴展,這些內容不在本文討論范圍之內。
就目前而言,system/application 文件夾中最重要的文件夾就是 config。該文件夾內有兩個需要關注的文件:config.php 和 database.php。
config.php 文件包含設置 CodeIgniter 所需的基本參數和自變量。database.php 文件包含連接數據庫所需的基本參數和自變量。
就目前而言,對于 config.php 文件,您只需設置
base_url
參數,例如設置為 http://127.0.0.1/CodeIgniter/。根據您正在使用的服務器地址更改此設置:
$config['base_url'] = "http://www.example.com/"; |
務必牢記添加最后的斜杠,即便是在子目錄中設置 CodeIgniter 應用程序時也是如此。
接下來,打開 database.php 文件,為數據庫服務器設置 connection 參數:
$db['default']['hostname'] = "your-db-host"; $db['default']['username'] = "your-username"; $db['default']['password'] = "your-password"; $db['default']['database'] = "your-db-name"; $db['default']['dbdriver'] = "mysql"; |
就是這樣。您還可以進行其他一些設置(如自動加載首選項和特殊路徑),但只要 CodeIgniter 了解它位于何處且可連接其底層數據庫,您就可以放心開始編寫代碼了。
現在,您已經安裝和配置了 CodeIgniter,接下來即可構建項目,這項工作至少要占用一個小時的時間。
這一次,我們不會構建 Hello World 應用程序,而是使用 CodeIgniter 創建一個簡單的 Web 站點。該站點將有一個主頁,顯示一些宣傳文本和一個表單,該表單將發布到數據庫表中。無需為其外觀費心 — 只需關注對應用程序有用的部分即可。換句話說,讓美工去關心外觀 — 您只要確保一切可以正常工作、迅速完成即可。
按照 CodeIgniter 的術語,可將這些需求轉換為以下內容:
- 一個控制器,僅包含少數功能(可使用默認的 Welcome 控制器)
- 一個模型(以及一個數據庫表),用于存儲聯系人信息
- 一個主視圖,包含一些支持
從模型入手可幫助您理解底層數據庫表,之后再開始布設功能和 UI。如果對表將存儲哪些內容認識不深,設計與表交互的表單將十分困難。
對于這個示例應用程序而言,您希望存儲的是來自表單的聯系人信息。那么需要的是哪些類型的聯系人信息?目前而言,僅存儲基本信息,要求提供姓名、電子郵件地址、電話號碼和簡短備注。您還可能希望在后臺存儲時間戳和 IP 地址。
MySQL 表應如下所示:
CREATE TABLE `contacts` ( `id` int(11) NOT NULL auto_increment, `name` varchar(128) NOT NULL, `email` varchar(255) NOT NULL, `notes` text NOT NULL, `stamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `ipaddress` varchar(32) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM; |
現在我們已經有了表,接下來將創建第一個模型。在 system/application/models 文件夾內,創建一個 mcontacts.php 文件。為什么要將其命名為 mcontacts?這是一種速記形式 — 文件名中在模型名前加一個 m 可幫助您記住文件的組織方式,而不必使用更長的前綴或后綴,如 model_ 等。
所有模型都采用相同的方式構造:
class MContacts extends Model{ function MContacts(){ parent::Model(); } } |
請注意,類名與文件名匹配,必須為類提供一個構造函數。換句話說,一個模型就是一個 PHP 類。這也就意味著模型中的所有函數實際上都是該類的一個方法。
理解這一點之后,很快就能領悟到,需要具備一個函數,將數據安全地插入聯系人數據庫表中。提供此功能的函數如下:
function addContact(){ $now = date("Y-m-d H:i:s"); $data = array( 'name' => $this->input->xss_clean($this->input->post('name')), 'email' => $this->input->xss_clean($this->input->post('email')), 'notes' => $this->input->xss_clean($this->input->post('notes')), 'ipaddress' => $this->input->ip_address(), 'stamp' => $now ); $this->db->insert('contacts', $data); } |
注意,您獲取了
POST
數組的輸出、整理并將其存儲在名為 contacts 的數據庫表中。在此過程中,您使用了多個幫助程序來簡化工作。
例如,
$this->input->xss_clean()
整理表單字段的數據、
$this->input->post()
簡化對這些表單字段的訪問、
$this->input->ip_address()
從用戶的瀏覽器獲取 IP 地址、
$this->db->insert()
向數據庫表添加一條新記錄。
在這種上下文中,
$this->input->xss_clean()
的使用必不可少 — 您正在處理 Web 用戶輸入,那可以是任何內容。使用
xss_clean()
函數或許是最基本的應對方法,您可能還要考慮應用更加穩妥的措施。添加功能來將字段長度縮短到一定大小可能也是一種合理做法。但就目前而言,
xss_clean()
例程即可為您提供足夠的保護。
您只用了短短幾分鐘就創建了一個可重用的函數,允許在數據庫中存儲聯系人信息。現在,我們將轉而討論控制器。
在 CodeIgniter 中,控制器用于組織項目。設想每個函數都是站點或應用程序的一個頁面或目標。如果使用主頁,就需要一個
index()
函數。如果有一個 About up 頁面,就需要
about()
或
about_us()
函數 — 具體取決于您希望怎樣構造 URL。
甚至可以將控制器組織到文件夾中,創建層次結構。例如,在 system/application/controllers 文件夾中,可能有一個 admin 文件夾,其中包含針對管理工具各主要部分的控制器。您可按照如下方法訪問這些控制器(和函數): http://www.example.com/admin/controller-name/function-name/。
目前只需使用默認控制器,即 Welcome 控制器。它存儲在 system/application/controllers/ 文件夾中,名為 welcome.php。打開時,應看到以下內容:
class Welcome extends Controller { function Welcome(){ parent::Controller(); } function index(){ $this->load->view('welcome_message'); } } |
如您所見,類名反映了文件名。這里也有一個構造函數,調用 CodeIgniter 內核中的父
Controller
類。了解這些就夠了。
接下來,注意名為
index()
的啟動函數,它將加載 welcome_message 視圖。在刪除此函數并編寫您自己的函數之前,有必要注意,此原型
index()
函數很好地滿足了為應用程序的最終用戶顯示信息的最低要求。
我們繼續構建一個新的
index()
函數。首先需要加載有用的 Form — 它能幫助您完成創建聯系人表單的繁瑣任務。
下面,設置可在視圖內部使用的多個變量 — 通過這種方法,即可更好地組織應用程序。例如,您可能希望在控制器中設置標題和標題欄。如果要這樣做,就必須將變量載入視圖。所載入的變量之一就是所包含視圖的名稱。通過這種方法,即可設置包含所有外觀的主視圖,以及包含內容的各包含項:
function index(){ $this->load->helper('form'); $data['title'] = "Welcome to our Site"; $data['headline'] = "Welcome!"; $data['include'] = 'home'; $this->load->vars($data); $this->load->view('template'); } |
$data
數組被傳入到一個稱為模板的視圖(接下來即將構建此視圖)。數組內的信息可使用鍵名訪問,如果希望輸出標題欄,通過
$headline
訪問它即可。
接下來,您將創建模板和主頁視圖(后者只是一個包含項),并完成控制器。
您的第一個視圖極為簡單 — 這是一個名為 template 的視圖。我們將盡力保持其簡單,展示視圖可以有多么靈活。template 視圖存儲為 system/application/views 中的 template.php,初始形式如下所示:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title></title> </head> <body> </body> </html> |
但應牢記,您正在傳入三個變量:
$title
、
$headline
和
$include
(一個包含項的名稱)。下面是添加了粗體所示內容后的 template 視圖:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title> <?php echo $title;?> </title> <style>label { display:block;}</style> </head> <body> <h1> <?php echo $headline;?> </h1> <?php $this->load->view($include);?> </body> </html> |
在添加的前兩條語句中,您將分別顯示在
$data['title']
和
$data['headline']
中找到的數據。隨后使用
$data['include']
的值載入第二個視圖。在本例中是一個名為 home 的視圖(另請注意,為了簡化后續的一些工作,我們還添加了少許 CSS 代碼)。
如果需要調用,那么最好首先進行構建。下面就是一個簡單的視圖,其中包含一個文本塊和一個從站點訪問者處收集信息的表單:
<p>This is random text for the CodeIgniter article. There's nothing to see here folks, just move along!</p> <h2>Contact Us</h2> <?php echo form_open('welcome/contactus'); echo form_label('your name','name'); $ndata = array('name' => 'name', 'id' => 'id', 'size' => '25'); echo form_input($ndata); echo form_label('your email','email'); $edata = array('name' => 'email', 'id' => 'email', 'size' => '25'); echo form_input($edata); echo form_label('how can you help you?','notes'); $cdata = array('name' => 'notes', 'id' => 'notes', 'cols' => '40', 'rows' => '5'); echo form_textarea($cdata); echo form_submit('submit','send us a note'); echo form_close(); ?> |
圖 2 顯示了將所有這些內容載入瀏覽器后的效果。
同樣,您使用了有用的 CodeIgniter 快捷方式集。這一次,使用的是 Form 幫助程序,將其載入控制器。
form_open()
函數允許打開表單 — 它具有必要的自變量,即表單發布的目標位置。下面,您將返回控制器并添加
contact()
函數來處理表單發布數據。
在表單中,您使用了
form_label()
來創建可訪問的標簽,使用
form_input()
和
form_textarea()
來構建表單字段和文本區,使用
form_submit()
來構建輸入按鈕。請注意,通過
form_input()
和
form_textarea()
(以及其他表單函數),您就可以傳入一個信息數組,幫助跟蹤字段名稱、id、大小和其他信息。
最后,使用
form_close()
關閉表單。
![]() |
|
讓我們回過頭來完成控制器。
現在已經有了兩個視圖,因而需要重新回到控制器,為其添加兩個函數。您已經了解了第一個函數:即處理主頁上的表單傳入的 POST 的
contactus()
函數。第二個是
thankyou()
函數,它將用作該表單的最終確認頁面。
contactus()
函數非常簡單。載入 MContacts 模型,運行該模型內的
addContact()
函數,然后將用戶轉向 thank-you 頁面。請注意,要使用
redirect()
函數,必須載入 URL 幫助程序。
代碼如下所示:
function contactus(){ $this->load->helper('url'); $this->load->model('MContacts','',TRUE); $this->MContacts->addContact(); redirect('welcome/thankyou','refresh'); } |
thankyou() 函數如下所示:
function thankyou(){ $data['title'] = "Thank You!"; $data['headline'] = "Thanks!"; $data['include'] = 'thanks'; $this->load->vars($data); $this->load->view('template'); } |
一切都非常簡單,thanks 視圖如下所示:
<p>Thanks so much for contacting us. Someone will be in contact with you soon.</p> |
您可能感到迷惑,為什么要為如此簡單的一個視圖浪費時間。為什么不在控制器中設置一個變量再運行它?當然可以那樣做,但分離函數組件總是最佳做法。通過這樣的方式,就不存在遇到任何麻煩的風險。
現在,還有一項工作需要完成。在 Welcome 控制器的
contactus()
函數中,有著在數據庫中創建多條空記錄的風險 — 這會導致某人連續將聯系人目標載入其瀏覽器或使用某種類型的機器人。
要避免此類情況發生,最簡單的方法就是在控制器中添加簡單的測試。如果存在
POST
數據,則載入模型和函數。如果沒有,則將其返回主頁。改寫后的函數如下所示:
function contact(){ $this->load->helper('url'); if ($this->input->post('email')){ $this->load->model('MContacts','',TRUE); $this->MContacts->addContact(); redirect('welcome/thankyou','refresh'); }else{ redirect('welcome/index','refresh'); } } |
在不到一個小時的時間里,您安裝并配置了 CodeIgniter,創建了一個包含主頁、將信息添加到數據庫的表單和 thank-you 頁面的 Web 站點。
當然,要學習的東西還有很多。例如,您可自動加載所需的模型和任何幫助程序或庫。可以為應用程序調整緩存和性能。可以為視圖添加更多 CSS 內容。可以添加在數據庫插入操作結束后發送電子郵件通知的功能。
目前,您只是掌握了開始使用 CodeIgniter 所需的一些內容。
文章來源: http://www.ibm.com/developerworks/cn/web/wa-codeigniter/index.html
附:
官方網站:
http://codeigniter.com
中文網站:
http://codeigniter.org.cn
中文手冊:
http://codeigniter.org.cn/user_guide
視頻教程:
http://codeigniter.org.cn/tutorials
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
