使用 CodeIgniter 快速簡單地創(chuàng)建 MVC 應用程序
Thomas Myer, 作者、顧問和 Web 開發(fā)人員, Triple Dog Dare Media
2008 年 9 月 16 日
創(chuàng)建 CodeIgniter 應用程序要比您想像中的容易。我將引導您創(chuàng)建第一個項目:一個帶有聯(lián)系人表單的簡單 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 開發(fā)人員,在使用 PHP 編程語言時不難發(fā)現(xiàn):大型項目可能會變得復雜。
這并非 PHP 的缺點。是的,這種語言提供了豐富的特性,而且具有足夠理想的彈性,可區(qū)分程序員之間的工作成果。在這種意義上,PHP 類似于 Perl,這是一些人喜歡它(而其他人鄙視它)的原因之一。任何曾經(jīng)查看過遺留 PHP 項目的有經(jīng)驗的 PHP 開發(fā)人員都可以輕松判斷出不同開發(fā)人員在項目不同階段的工作 — 就像您是一位考古學家,正在凝視著深深的墓穴,見證著不同文化在各自時代的發(fā)展。
不管涉及了什么樣式或使用了什么方法,超過幾千行代碼的 PHP 項目很容易在倉促之中變得凌亂不堪。這主要是因為它們在結構上不一致。一些程序員創(chuàng)建類來組織其工作,但似乎沒有任何兩個程序員對于如何編寫類具有相同的看法。其他程序員構建大量充滿函數(shù)的包含文件。還有其他人使用巨大、獨立的庫,比如 PEAR。
在幾年前,PHP 一直缺乏一個良好的、功能完善的模型-視圖-控制器(Model-View-Controller,MVC)框架。MVC 框架允許程序員將其代碼組織為三個不同的功能區(qū):
- 模型 包含與您的數(shù)據(jù)庫和其他數(shù)據(jù)結構相關的所有代碼。如果您具有一個名為 pages 的表,則您具有一個模型,其中具有用于從表中選擇、創(chuàng)建、更新和刪除記錄的函數(shù)。
- 視圖 包含所有顯示和 UI 元素 — JavaScript 代碼、Cascading Style Sheets (CSS)、HTML 甚至 PHP。
-
控制器
將一切聯(lián)系在一起。控制器中的每個函數(shù)表示一個目的地或路線。如果您具有一個名為 /about 的目的地,則控制器將具有一個名為
about()的函數(shù)。
如果以前沒有使用過 MVC 框架,上述三點無法體現(xiàn)出這種組織模式的強大之處。一旦您開始用 MVC 思考,您對 PHP 開發(fā)的觀點和態(tài)度將發(fā)生顯著變化。
例如,不是在項目的每個可用角落中都塞入數(shù)據(jù)庫查詢代碼,而是將一切都組織到模型中。為了從數(shù)據(jù)庫表中選擇頁面,可以使用頁面模型中的函數(shù)。
同樣地,如果您需要更新特定頁面的外觀,可以使用視圖,而不用與控制器打交道。與此類似,控制器是為您的應用程序添加目標和其他控制代碼的位置;不必在模型中放入任何此類東西。
無論使用哪種 MVC 框架,在一天之內(nèi),您就會意識到您具有一個容易記住、可按需擴展的系統(tǒng)。如果客戶在下周需要更改,沒問題 — 您可以搞定。如果第二年有什么請求,同樣如此。
在所有 MVC 框架中,最著名的莫過于 Ruby on Rails。多年以前,它席卷 Web 開發(fā)領域,滿足了所有人的想像。它并非純粹的 MVC 框架,而是一種約定優(yōu)于配置的 MVC 框架。
約定優(yōu)于配置 意味著使用 Rails 時,您需要設置一些關鍵配置項(例如數(shù)據(jù)庫的位置、特定用戶名和路徑),其他配置均由智能默認設置處理,您可在隨后修改,也可不加修改。
結果不僅僅能得到組織良好的代碼,而且還有速度極快、易于使用的 Web 開發(fā)環(huán)境。這都是 PHP 世界的夢想。經(jīng)過一兩年之后,許多類似于 Rails 的工具紛紛出現(xiàn):CakePHP、Symfony 等等。
最終,EllisLab 的工作人員發(fā)布了 CodeIgniter。許多企業(yè)嘗試體驗過所有 PHP MVC 框架之后,CodeIgniter 都成為贏家,主要是由于它為組織提供了足夠的自由支持,允許開發(fā)人員更迅速地工作。
自由意味著使用 CodeIgniter 時,您不必以某種方式命名數(shù)據(jù)庫表,也不必根據(jù)表命名模型。這使 CodeIgniter 成為重構遺留 PHP 應用程序的理想選擇,在此類遺留應用程序中,可能存在需要移植的所有奇怪的結構。
CodeIgniter 不需要大量代碼(1.6.2 版本僅為 2.8 MB,其中的 1.3 MB 是可以刪除的用戶文檔),也不會要求您插入類似于 PEAR 的龐大的庫。它在 PHP 4 和 PHP 5 中表現(xiàn)同樣良好,允許您創(chuàng)建可移植的應用程序。最后,您不必使用模板引擎來創(chuàng)建視圖 — 只需沿用舊式的 HTML 和 PHP 即可。
至此,我們已經(jīng)提供了足夠的介紹,下面來構建一個簡單的項目,看看它的效果。
在構建任何 CodeIgniter 新項目時,第一步都是下載最新軟件包(在本文撰寫時,最新軟件包是 1.6.2,請參見 參考資料 小節(jié))。下載壓縮存檔文件(.zip)并解壓縮之后,您就獲得了一個 codeigniter_ <version_number> 文件夾,其中包括開始創(chuàng)建所必須的一切內(nèi)容。
在進行一組必需的輕微的配置更改之前,本節(jié)將為您簡單介紹 CodeIgniter,使您熟悉它的基礎知識。
打開 CodeIgniter 文件夾時,您會看到一個名為 system 的文件夾。所有 CodeIgniter 代碼都將存放在這里。在此文件夾內(nèi)還有一些文件夾,其中有一個名為 application:您要處理的 99.999% 的文件都將位于此文件夾內(nèi)。該文件夾的命名十分貼切,因為它包含您的應用程序及其所有組成部分 — system 文件夾的其他部分包括 CodeIgniter 核心代碼和其他不應混淆的文件。
application 文件夾下又分為多個文件夾(參見 圖 1 )。大多數(shù)文件夾易于理解。模型存放在 models 文件夾中、視圖存放在 views 文件夾中、控制器存放在 controllers 文件夾中,依此類推。還有一些文件夾用于存儲 CodeIgniter 幫助程序和庫的本地擴展,這些內(nèi)容不在本文討論范圍之內(nèi)。
就目前而言,system/application 文件夾中最重要的文件夾就是 config。該文件夾內(nèi)有兩個需要關注的文件:config.php 和 database.php。
config.php 文件包含設置 CodeIgniter 所需的基本參數(shù)和自變量。database.php 文件包含連接數(shù)據(jù)庫所需的基本參數(shù)和自變量。
就目前而言,對于 config.php 文件,您只需設置
base_url
參數(shù),例如設置為 http://127.0.0.1/CodeIgniter/。根據(jù)您正在使用的服務器地址更改此設置:
$config['base_url'] = "http://www.example.com/";
|
務必牢記添加最后的斜杠,即便是在子目錄中設置 CodeIgniter 應用程序時也是如此。
接下來,打開 database.php 文件,為數(shù)據(jù)庫服務器設置 connection 參數(shù):
$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 了解它位于何處且可連接其底層數(shù)據(jù)庫,您就可以放心開始編寫代碼了。
現(xiàn)在,您已經(jīng)安裝和配置了 CodeIgniter,接下來即可構建項目,這項工作至少要占用一個小時的時間。
這一次,我們不會構建 Hello World 應用程序,而是使用 CodeIgniter 創(chuàng)建一個簡單的 Web 站點。該站點將有一個主頁,顯示一些宣傳文本和一個表單,該表單將發(fā)布到數(shù)據(jù)庫表中。無需為其外觀費心 — 只需關注對應用程序有用的部分即可。換句話說,讓美工去關心外觀 — 您只要確保一切可以正常工作、迅速完成即可。
按照 CodeIgniter 的術語,可將這些需求轉(zhuǎn)換為以下內(nèi)容:
- 一個控制器,僅包含少數(shù)功能(可使用默認的 Welcome 控制器)
- 一個模型(以及一個數(shù)據(jù)庫表),用于存儲聯(lián)系人信息
- 一個主視圖,包含一些支持
從模型入手可幫助您理解底層數(shù)據(jù)庫表,之后再開始布設功能和 UI。如果對表將存儲哪些內(nèi)容認識不深,設計與表交互的表單將十分困難。
對于這個示例應用程序而言,您希望存儲的是來自表單的聯(lián)系人信息。那么需要的是哪些類型的聯(lián)系人信息?目前而言,僅存儲基本信息,要求提供姓名、電子郵件地址、電話號碼和簡短備注。您還可能希望在后臺存儲時間戳和 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;
|
現(xiàn)在我們已經(jīng)有了表,接下來將創(chuàng)建第一個模型。在 system/application/models 文件夾內(nèi),創(chuàng)建一個 mcontacts.php 文件。為什么要將其命名為 mcontacts?這是一種速記形式 — 文件名中在模型名前加一個 m 可幫助您記住文件的組織方式,而不必使用更長的前綴或后綴,如 model_ 等。
所有模型都采用相同的方式構造:
class MContacts extends Model{
function MContacts(){
parent::Model();
}
}
|
請注意,類名與文件名匹配,必須為類提供一個構造函數(shù)。換句話說,一個模型就是一個 PHP 類。這也就意味著模型中的所有函數(shù)實際上都是該類的一個方法。
理解這一點之后,很快就能領悟到,需要具備一個函數(shù),將數(shù)據(jù)安全地插入聯(lián)系人數(shù)據(jù)庫表中。提供此功能的函數(shù)如下:
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
數(shù)組的輸出、整理并將其存儲在名為 contacts 的數(shù)據(jù)庫表中。在此過程中,您使用了多個幫助程序來簡化工作。
例如,
$this->input->xss_clean()
整理表單字段的數(shù)據(jù)、
$this->input->post()
簡化對這些表單字段的訪問、
$this->input->ip_address()
從用戶的瀏覽器獲取 IP 地址、
$this->db->insert()
向數(shù)據(jù)庫表添加一條新記錄。
在這種上下文中,
$this->input->xss_clean()
的使用必不可少 — 您正在處理 Web 用戶輸入,那可以是任何內(nèi)容。使用
xss_clean()
函數(shù)或許是最基本的應對方法,您可能還要考慮應用更加穩(wěn)妥的措施。添加功能來將字段長度縮短到一定大小可能也是一種合理做法。但就目前而言,
xss_clean()
例程即可為您提供足夠的保護。
您只用了短短幾分鐘就創(chuàng)建了一個可重用的函數(shù),允許在數(shù)據(jù)庫中存儲聯(lián)系人信息。現(xiàn)在,我們將轉(zhuǎn)而討論控制器。
在 CodeIgniter 中,控制器用于組織項目。設想每個函數(shù)都是站點或應用程序的一個頁面或目標。如果使用主頁,就需要一個
index()
函數(shù)。如果有一個 About up 頁面,就需要
about()
或
about_us()
函數(shù) — 具體取決于您希望怎樣構造 URL。
甚至可以將控制器組織到文件夾中,創(chuàng)建層次結構。例如,在 system/application/controllers 文件夾中,可能有一個 admin 文件夾,其中包含針對管理工具各主要部分的控制器。您可按照如下方法訪問這些控制器(和函數(shù)): http://www.example.com/admin/controller-name/function-name/。
目前只需使用默認控制器,即 Welcome 控制器。它存儲在 system/application/controllers/ 文件夾中,名為 welcome.php。打開時,應看到以下內(nèi)容:
class Welcome extends Controller {
function Welcome(){
parent::Controller();
}
function index(){
$this->load->view('welcome_message');
}
}
|
如您所見,類名反映了文件名。這里也有一個構造函數(shù),調(diào)用 CodeIgniter 內(nèi)核中的父
Controller
類。了解這些就夠了。
接下來,注意名為
index()
的啟動函數(shù),它將加載 welcome_message 視圖。在刪除此函數(shù)并編寫您自己的函數(shù)之前,有必要注意,此原型
index()
函數(shù)很好地滿足了為應用程序的最終用戶顯示信息的最低要求。
我們繼續(xù)構建一個新的
index()
函數(shù)。首先需要加載有用的 Form — 它能幫助您完成創(chuàng)建聯(lián)系人表單的繁瑣任務。
下面,設置可在視圖內(nèi)部使用的多個變量 — 通過這種方法,即可更好地組織應用程序。例如,您可能希望在控制器中設置標題和標題欄。如果要這樣做,就必須將變量載入視圖。所載入的變量之一就是所包含視圖的名稱。通過這種方法,即可設置包含所有外觀的主視圖,以及包含內(nèi)容的各包含項:
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
數(shù)組被傳入到一個稱為模板的視圖(接下來即將構建此視圖)。數(shù)組內(nèi)的信息可使用鍵名訪問,如果希望輸出標題欄,通過
$headline
訪問它即可。
接下來,您將創(chuàng)建模板和主頁視圖(后者只是一個包含項),并完成控制器。
您的第一個視圖極為簡單 — 這是一個名為 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
(一個包含項的名稱)。下面是添加了粗體所示內(nèi)容后的 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']
中找到的數(shù)據(jù)。隨后使用
$data['include']
的值載入第二個視圖。在本例中是一個名為 home 的視圖(另請注意,為了簡化后續(xù)的一些工作,我們還添加了少許 CSS 代碼)。
如果需要調(diào)用,那么最好首先進行構建。下面就是一個簡單的視圖,其中包含一個文本塊和一個從站點訪問者處收集信息的表單:
<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 顯示了將所有這些內(nèi)容載入瀏覽器后的效果。
同樣,您使用了有用的 CodeIgniter 快捷方式集。這一次,使用的是 Form 幫助程序,將其載入控制器。
form_open()
函數(shù)允許打開表單 — 它具有必要的自變量,即表單發(fā)布的目標位置。下面,您將返回控制器并添加
contact()
函數(shù)來處理表單發(fā)布數(shù)據(jù)。
在表單中,您使用了
form_label()
來創(chuàng)建可訪問的標簽,使用
form_input()
和
form_textarea()
來構建表單字段和文本區(qū),使用
form_submit()
來構建輸入按鈕。請注意,通過
form_input()
和
form_textarea()
(以及其他表單函數(shù)),您就可以傳入一個信息數(shù)組,幫助跟蹤字段名稱、id、大小和其他信息。
最后,使用
form_close()
關閉表單。
|
|
|
讓我們回過頭來完成控制器。
現(xiàn)在已經(jīng)有了兩個視圖,因而需要重新回到控制器,為其添加兩個函數(shù)。您已經(jīng)了解了第一個函數(shù):即處理主頁上的表單傳入的 POST 的
contactus()
函數(shù)。第二個是
thankyou()
函數(shù),它將用作該表單的最終確認頁面。
contactus()
函數(shù)非常簡單。載入 MContacts 模型,運行該模型內(nèi)的
addContact()
函數(shù),然后將用戶轉(zhuǎn)向 thank-you 頁面。請注意,要使用
redirect()
函數(shù),必須載入 URL 幫助程序。
代碼如下所示:
function contactus(){
$this->load->helper('url');
$this->load->model('MContacts','',TRUE);
$this->MContacts->addContact();
redirect('welcome/thankyou','refresh');
}
|
thankyou() 函數(shù)如下所示:
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>
|
您可能感到迷惑,為什么要為如此簡單的一個視圖浪費時間。為什么不在控制器中設置一個變量再運行它?當然可以那樣做,但分離函數(shù)組件總是最佳做法。通過這樣的方式,就不存在遇到任何麻煩的風險。
現(xiàn)在,還有一項工作需要完成。在 Welcome 控制器的
contactus()
函數(shù)中,有著在數(shù)據(jù)庫中創(chuàng)建多條空記錄的風險 — 這會導致某人連續(xù)將聯(lián)系人目標載入其瀏覽器或使用某種類型的機器人。
要避免此類情況發(fā)生,最簡單的方法就是在控制器中添加簡單的測試。如果存在
POST
數(shù)據(jù),則載入模型和函數(shù)。如果沒有,則將其返回主頁。改寫后的函數(shù)如下所示:
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,創(chuàng)建了一個包含主頁、將信息添加到數(shù)據(jù)庫的表單和 thank-you 頁面的 Web 站點。
當然,要學習的東西還有很多。例如,您可自動加載所需的模型和任何幫助程序或庫。可以為應用程序調(diào)整緩存和性能。可以為視圖添加更多 CSS 內(nèi)容。可以添加在數(shù)據(jù)庫插入操作結束后發(fā)送電子郵件通知的功能。
目前,您只是掌握了開始使用 CodeIgniter 所需的一些內(nèi)容。
文章來源: http://www.ibm.com/developerworks/cn/web/wa-codeigniter/index.html
附:
官方網(wǎng)站:
http://codeigniter.com
中文網(wǎng)站:
http://codeigniter.org.cn
中文手冊:
http://codeigniter.org.cn/user_guide
視頻教程:
http://codeigniter.org.cn/tutorials
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

