簡化 HTML 頁面和表格設計
這一章介紹了又一個節約你的時間並且使你的代碼更具安全性和邏輯性的領域。
第一,咱們將會介紹建立視圖的各類不一樣方法-與你的控制器和模型協同並用來顯示結果的頁面。
而後,你將會學到如何很快地建立 HTML 表格, 與實現內建的保護; 並且你也將會看到該如何校驗你的表格。
我假定這本書的讀者熟悉 HTML 和 CSS 。 下列的例子很是簡單,所以,咱們能把重點放在 CI 代碼上。 並且我已經假定咱們已經寫一個 CSS 文件並已把它保存在網站的某個目錄中。
編寫視圖
視圖是用戶用戶能看到你的網站的全部。 他們使用一個統一的接口, 並且能夠根據須要進行修改。 MVC 的好處之一是你分開了表示層和邏輯層, 一切都顯得很乾淨。
到如今爲止, 咱們已經完成了那很是簡單的 'welcome' 頁面,(記得第 3 章嗎?) 如今讓咱們看看該如何使它變得更精細。
視圖其實是一組包含有你的內容的HTML結構。結構中有各類元素,如顏色,字體,文字佈局等; 不過視圖不關心這些,它要作的只是取來內容,顯示出來。
建立視圖, 首先你須要建立一個HTML 網頁的骨架,並保存爲.php後綴。 讓咱們稱它爲 basic_view.php 。保存在application/views目錄中。 (CI的loader會在這個目錄尋找視圖文件。)
<html>
<head>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
而後當你想要從一個控制器裝載它時, 使用在某個函數中調用$this->load->view():
function index() {
$this->load->view('basic_view');
}
注意,若是這是一個model或者一個helper,你將會首先裝載它, 而後根據須要使用它。 經過視圖,調用它只須要一行代碼。
固然,那是一個空的視圖。 爲了要使它有用,咱們須要內容。所以咱們要增長名稱和一些文本。 首先咱們在控制器中定義他們:
function() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep track of the other websites you control";
}
注意咱們並無把它們定義爲單獨的變量, 而是做爲數組$data的元素。 對於第一個元素, 鍵名是 'mytitle',值是 "A website monitoring tool".
而後,咱們調用裝載函數:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep track of the other websites you control.";
$this->load->view('basic_view',$data);
}
咱們把$data數組做爲$this->load->view()的第二個叄數,在視圖名稱以後。視圖接收到$data數組後,使用PHP函數extract()把數組中的每一個元素轉換成內存變量,數組的鍵名即爲變量名,值爲變量內所包含的值。這些變量的值能直接被視圖引用:
<html>
<head>
</head>
<body>
<h1 class='test'><?php echo $mytitle; ?></h1>
<p class='test'><?php echo $mytext; ?></p>
</body>
</html>
雖然你只能傳送一個變量到視圖, 可是經過創建數組,你能把大量變量整潔地傳入視圖。它彷佛複雜, 可是其實是一種緊湊和優秀的信息傳輸方式。
PHP標記的長格式和短格式
在咱們繼續以前, 先了解一下PHP標記的兩種不一樣格式。
經常使用的方式是:
<?php echo $somevariable?>
然而,若是你不喜歡這種, CI 也支持一個較短的版本:
<?=$somevariable?>
<?php ?>被<??>取代,並且echo由「=」代替,你也能用短格式來使用if, for, foreach, 和while循環。完整的介紹請參考在線用戶手冊。
我我的偏好標準格式,由於我已習慣使用它。若是你使用短格式,注意有些服務器不能正確地解釋短格式。 若是你仍然想要使用短標籤, 能夠打開 config 文件, 改變下列設置:
$config['rewrite_short_tags']= FALSE;
如設置爲TRUE,CI在把它們送到服務器以前,將把短格式改爲標準格式。 不過這樣作會對調試形成困難。所以,建議使用標準格式。
CI 也有一個 '模板語法分析器' 類,容許你把變量放入HTML代碼而不須要任何的PHP代碼。本文不涉及這個內容。若是在與可能被 PHP 代碼弄糊塗的 HTML 設計者合做,它至關有用,細節請參見用戶手冊。
嵌套視圖
爲了最大程度地重用代碼,咱們能夠提取HTML頁面的公共部分,例如,header和footer,而後在顯示實際視圖時把它們組合起來。
讓咱們建立一個視圖的header部分, 這是一個符合W3C標準的header、包含HTML聲明和 meta數據。
首先, 咱們列出header部分的代碼:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 strict//EN'http://www.w3.org/TR/xhtml1/DTD/xhtml-strict.dtd'>< html xmlns='http://www.w3.org/1999/xhtml'>
<title><?php echo $mywebtitle?></title>
<base href=<?php echo "$base"; ?>>
<?php echo $myrobots?>
<link=" stylesheet" type="text/css" href="<?php echo "$base/$css;?>">
把這保存爲views/header_view. 下面介紹它包含的變量:
。$mywebtitle, 是標題 (meta標籤; 這將不在屏幕上出現,可是搜索引擎將會讀取,每一個頁面的meta有可能有變化,所以,我把它設爲一個變量。)
。$myrobots, 這個變量用來告訴機器人當前頁面不須要被編入索引。
。$base和 $css, 描述基本網址的字符串。$css包含css文件的路徑信息, 這些信息會從CI的config 文件讀取(也能夠用 CI config 變量 site_url代替。)
如今咱們須要知道:
。咱們如何調用嵌套視圖?
。咱們如何獲取變量的值?
有二個方法可選擇。 第一,在主調用視圖中讀入其它視圖,所以咱們的主視圖,也就是basic_view,應該加上一行:
<html><head>
<?php $this->load->view ('header_view'); ?>
</head><body>
<?php echo $mytitle; ?>
<?php echo $mytext; ?>
</>
</html>
變量能夠在控制器中加上兩行:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep
track of the other websites you control.";
$data['myrobots'] = '<meta name="robots" content
="noindex,nofollow">';
$data['mywebtitle'] = 'Web monitoring tool';
$data['base'] = $this->config->item('base_url');
$data['css'] = $this->config->item('css');
$this->load->view('basic_view',$data);
}
在這裏新的變量 $myrobots,$css, $base, $mywebtitle被建立爲數組$data的新元素,當header_view被basic_view調用時,CI使用extract()解開他們, 在視圖中顯示出來(在兩個視圖中不要出現同名的變量,不然會引發衝突)。
第二個方法將把視圖加入控制器裏面, 給它分配一個變量:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep
track of the other websites you control.";
$data['myrobots'] = '<meta name="robots" content
="noindex,nofollow">';
$data['mywebtitle'] = 'Web monitoring tool';
$data['base'] = $this->config->item('base_url');
$data['css'] = $this->config->item('css');
$data['header'] = $this->load->view('header_view', '', TRUE);
$this->load->view('basic_view',$data);
}
從嚴格的 MVC 設計原則來看,這樣作彷佛更正確。
實際上有三個叄數可傳給load->view函數。
。 第一個, header_view, 是要裝載的視圖的名字。 這是必選。
。 第二個,是可選項, 是裝入視圖的數據。
。 第三個是布爾值。若是你不指定它,默認是FALSE, 將視圖送到瀏覽器。 然而,在嵌套視圖這種狀況下,你須要將header_view送到主視圖basic_view中,所以須要將第三項參數設置爲TRUE。
如今咱們已經創建了與 stylesheet 的關聯, 咱們可以用定義好的css中的類來更新視圖中的顯示部分:
<html><head>
<?php $this->load->view('header_view'); ?>
</head><body>
<h1 class='test'><?php echo $mytitle; ?></h1>
<p class='test'><?php echo $mytext; ?></p>
</body>
</html>
請注意CI的 MVC 系統能讓你分離顯示的內容。 視圖只爲內容提供結構, 結構的風格則由css stylesheet控制。
視圖不關心什麼 $mytext的內容是什麼,它只是按照正確的格式在正確的位置上顯示它。 定義 $mytext 的控制器甚至不知道 (也不關心) 它產生的數據如何被顯示。
所以, 若是咱們須要改變咱們網頁的外觀, 或在一個不一樣的系統 (如WAP)上顯示他們,那麼咱們只須要改變視圖和CSS stylesheet。 咱們不須要修改控制器。
並且若是咱們想要改變在網頁上的信息,咱們不須要去改動視圖, 而是隻須要改變控制器裏的變量值。
記得 '鬆藕合' 原則嗎? 這裏再一次體會到了這個原則,這使設計,升級, 和維持你的網站比較容易。
網站結構的現實問題
請稍等片刻,咱們在header_view動態地生成了 CSS stylesheet地址:
<link="stylesheet" type="text/css" href="<?php echo "$base/$css";?>">
這意味着控制器必須生成變量的值,這些值與數據如何被顯示有關, 可是咱們在上面說過控制器不該該知道或者關心它們具體的值是什麼。這樣不就符合了咱們剛纔說起的所謂'鬆藕合'原則? 動態地產生這些數據須要這樣一些操做: 首先,控制器必須在 config 文件中讀取它們,而後控制器必須在$data數組中裝入它們並且傳送它們到視圖,而後視圖必須解開成爲內存變量$base和$css, 真正使用這兩個變量的是HTML協議。
彷佛這樣作太繞圈子了,爲何不直接在視圖中靜止地插入數據?
<link="stylesheet" type="text/css" href="http://www.mysite.com/mystylesheet.css";">
用變量方式作這件事情的好處是:若是你遷移網站, 或移動你的 CSS 文件,你只須要在 config 文件中改變設置,並且每一個控制器和視圖將會馬上反映變化。 而若是把CSS位置硬編碼到每一個視圖的後果是一旦須要變化,你必須到每一個視圖中去修改它們,明白這樣作的好處了吧?
CI 的表格助手: 錄入數據
讓咱們把目光轉向你如何使用你的 HTML 頁。任何動態的網站最重要部份之一是和用戶互動,並且這一般意味着使用 HTML 表格。 編寫表格是重複和無聊的。
CI 的表格助手是密碼的很是有用的代碼片段。 它有一個稍稍不一樣的定義, 使表格建立起來比較容易。 讓咱們創建一個表格,這個表格容許咱們在瀏覽器中錄入數據。 在websites數據庫的sites表中,咱們想要錄入網站的名字、類型和網址, 和更新的日期。
你能用簡單的 HTML代碼 創建表格, 或你能在一個控制器內創建它,把它賦給一個變量, 而後調用視圖, 並且傳送該變量到視圖。 我正在按第二種方式作。
第一,咱們必須裝載表格助手到咱們須要使用它的控制器內。 而後, 咱們把下列的代碼放入控制器的構造函數:
$this->load->helper('form');
而後,咱們必須開始編寫表格。
如今, 爲了生成表格的輸入項, 咱們不用這樣寫:
$variable .= <input type='text' name='name' value=''>
CI 讓你這樣作:
$variable .= form_input('name','');
(記得'name'是輸入項的名稱, 'value'是你想輸入的內容。 在這裏能夠設定value的初始值,或你能動態地從表格中獲取.)
能夠看到,使用CI的表格助手列方便。
使用表格助手的好處之一: 清楚
使用 CI 表格助手的第一個利益是你的代碼絕對的清楚。 若是你想要一個比較精細的輸入框, 若是用HTML是這樣的:
$variable = 'input type="text" name=" url" id="url" value=" www.mysite.com" maxlength="100" size="50" style="yellow"/>';
name是將在$_POST數組中取得的變量名稱。
id是在網頁上定位這個輸入框的標識符,若是你使用JavaScript的話。
value是輸入框裏顯示的值,它一開始是一個默認值,用戶也能夠在輸入一個新的值。
maxlength 和size是明顯的; style一組 HTML 格式或者在css stylesheet 中定義。)
CI 用一個數組代替上述的HTML代碼:
$data = array(
'name' => 'url',
'id' => 'url',
'value' => 'www.mysite.com',
'maxlength'=> '100',
'size' => '50',
'style' => 'yellow',
);
$variable = form_input($data);
它看上去蠻長的, 實際上並不比HTML代碼長,並且,它很是清楚, 容易理解和維護。並且是動態的。
隱藏的表格輸入框很是簡單。若是咱們想要自動地記錄咱們的數據庫被更新的日期。 咱們把日期放入一個$date變量, 而後:
form_hidden('updated', $date);
若是你想要一個'文本'輸入框, 給你的使用者提供一個能夠輸入超過一行的地方,可使用CI的form_textarea()函數,下面的代碼使用默認的長度,在網頁上顯示一個文件輸入框:
$data = array(
'name' => 'url',
'id' => 'url',
'value' => 'www.mysite.com',
);
$variable = form_textarea($data);
CI的表格助手在你編寫下拉框,多選框和單選框時特別有用,若是咱們要改變咱們的URL輸入框爲一個下拉框,容許用戶從下拉列表中選取一個URL。首先,把下拉列表的選項存入一個數組,而後調用form_dropdown()函數:
$urlarray= array(
'1' => 'www.this.com',
'2' => 'www.that.com',
'3' => 'www.theother.com',
);
$variable = form_dropdown('url' 、 $urlarray, '1');
被傳給表格中url下拉框的第一個參數是輸入框的名字; 第二個是包含下拉列表的數組,第三個默認選項。 換句話說,若是使用者接受默認值, 你的 $_POST數組將會包含值 'url=>1' ,可是你的用戶將會見到選項 'www.this.com'.
若是使用HTML代碼編寫:
<select name="type">
<option value="1" selected>www.this.com</option>
<option value="2">www.that.com</option>
<option value="3">www.theother.com</option>
</select>
CI實現的代碼實際上比較短, 很容易學會。
若是你在一個數據庫表('urls')中儲存你的可能選擇的網址的目錄,那麼生成一個動態下拉框很容易。 首先把數據從表中讀出放到一個數組中:
$urlarray = array();
$this->db->select('id,url');
$query = $this->db->get('urls');
if ($query->num_rows()>0) {
foreach($query->result() as $row) {
$urlarray[$row->id] = $row->url;
}
}
而後重複咱們之前用過的 CI form_dropdown() 功能:
echo form_dropdown('type', $urlarray,'1');
只有$urlarray 的內容會發生變化; 代碼老是同樣的。
若是你正在更新一個表中的記錄而不是插入, 你不想爲你的用戶顯示默認值。你想要爲那一個記錄顯示已經存在的值。你應該已經知道你想要的修改的記錄的id值,所以,你須要先讀取數據庫中'site'表中相關記錄。肯定把查詢結果賦給一個變量,使用第二個變量取出第一個變量的中的相關記錄, 再調用CI的form_dropdown函數,把第二個變量和對應的列名做爲參數傳入:
$this->db->select('id, url, name');
$this->db->where('id','$id');
$sitequery = $this->db->get('sites');
$siterow = $sitequery->row();
而後你的 CI 下拉框函數會從中讀取相關信息:
echo form_dropdown('url' 、 $urlarray, $siterow->url);
本書沒有太多的篇幅討論全部的表格助手。 它還能編寫單選框,隱藏文件框,多選框和一些其它的輸入框,完整的資料請參考CI用戶手冊。
表格助手的好處之二: 自動化
使用表格助手的第二個好處是能夠自動化實現一些功能,否則的話,你只能本身編寫相關的腳本了。
首先, 它攔截HTML的一些字符,好比用戶輸入的引號,而且轉義它們以避免破壞表格。
其次,它自動鏈接。當你打開一個表格時,你必須聲明目標頁,它將會接受表格的數據而且處理它。(在CI中,這是一個控制器裏面的一個功能而不是一個靜態頁。 好比它指向控制器的更新函數.) 所以,若是你正在使用簡單的 HTML 代碼,你將會這樣寫:
<form method="post" action="http:/www.mysite.com/index.php/websites/update"/>
若是你用 CI 打開你的表格,你只須要這樣作:
form_open(websites/update);
CI 自動地在你的 config 文件中取出基本URL並定位到對應的控制器函數。 再次強調,若是你遷移你的網站,你只須要修改config文件,而不是去一個一個地修改代碼文件。
順便提一下, CI 假定你的表格將會老是以POST的方式提交數據而不是GET方式。CI廣泛使用URL自己,所以,不要搞錯。
個人 '顯示' 模型
做爲示範(稍微簡化了一下),這裏是個人顯示模型:
<?php
class Display extends Model {
/*create the array to pass to the views*/
var $data = array();
/*two other class variables*/
var $base;
var $status = '';
/*
the constructor function: this calls the 'model' parent class, loads other CI libraries and helpers it requires, and dynamically sets variables
*/
function Display()
{
parent::Model();
$this->load->helper('form');
$this->load->library('user_agent');
$this->load->library('errors');
$this->load->library('menu');
$this->load->library('session');
/*now set the standard parts of the array*/
$this->data['css'] = $this->config->item('css');
$this->data['base'] = $this->config->item('base_url');
$this->base = $this->config->item('base_url');
$this->data['myrobots'] = '<meta name="robots"
c>';
/*
note that CI's session stuff doesn't automatically recall the extra variables you have added, so you have to look up the user's status in the ci_sessions table
*/
$sessionid = $this->session->userdata('session_id');
$this->db->select('status');
$this->db->where('session_id', $sessionid);
$query = $this->db->get('ci_sessions');
if ($query->num_rows() > 0)
{
$row = $query->row();
$this->status = $row->status;
}
}
/*
function to assemble a standard page. Any controller can call this. Just supply as $mydata an array, of key/value pairs for the contents you want the view to display. Available variables in this view are:
mytitle. menu, mytext, diagnostic
*/
function mainpage($mydata)
{
$this->data['mytitle'] = 'Monitoring website';
$this->data['diagnostic'] = $diagnostic;
foreach($mydata as $key => $variable)
{$this->data[$key] = $variable;}
/*here's the menu class we looked at in Chapter 3*/
$fred = new menu;
$this->load->library('session');
$mysess = $this->session->userdata('session_id');
if(isset($this->status) && $this->status > 0)
{$this->data['menu']=
$fred->show_menu($this->status);}
$this->load->view('basic_view', $this->data);
}
}
?>
我能用下面的代碼在任何的控制器中調用這個主頁:
$this->load->model('display');
$this->display->mainpage($data);
而且我也知道個人視圖正在被動態地裝配,徹底符合個人須要。
CI 的校驗類: 方便地檢驗數據
在你編寫HTML表格時一個重要的工做是檢查輸入。咱們都知道咱們應該這樣作,可是…直到如今爲止,咱們已經編寫過一種簡單的表格, 將會信任地接受任何用戶輸入的任何數據。 你應該意識到可能有一些用戶是不懷好意的,並且全部的其他都是不負責任的。(別直接告訴他們.) 若是他們有可能犯一個簡單的錯誤,他們就會犯。確保你始終檢查用戶輸入的數據,並使它們符合你的要求。
你能在客戶端用javascript作到這一點, 可是這樣作做用有限,使用者能容易地繞過它。 而在服務器端的校驗須要一個額外的信息來回,這點額外的開銷是值得的。
編寫校驗代碼也至關複雜, 可是-你必定猜到了-CI 提供了一個校驗類可使這項工做變得很是容易。
讓咱們改變咱們本身的表格處理過程來實現校驗。 你須要在表格裏做一些調整, 還要在它指向的函數裏做一些調整。
若是你的表格由 form_open('sites/update') 開始, 你須要修改的函數是'sites控制器裏的'update'函數。 若是你沒有使用 CI 的表格助手, HTML等價代碼是:
<form method="post" action="http://www.mysite.com/index.php/sites/update"/>
你須要作三件事情:
1. 設置校驗
2. 設置控制器
3. 設置表格
設置校驗
在你的表格指定的那個函數中裝載校驗類並聲明你的校驗規則:
$this->load->library('validation');
$rules['url'] = "required";
$rules['name'] = "required";
$this->validation->set_rules($rules);
'url'和 'name'輸入框必定要有輸入內容。 CI提供了各類操做,確保一些操做必定要進行,用戶手冊全面地解釋了這些內容。 他們的含義很是明瞭: min_length[6] 顯然意味着輸入的信息長度必定要大於等於六個字符。numeric意味着只能輸入數字,等等。你還能組合規則,用「|」把它們鏈接起來:
$rules['name'] = "required |alpha| max_length[12]";
意味着不能爲空,字母,長度至少12個字符。你甚至能編寫你本身的規則。
設置控制器
仍然在相同的函數中,建立一個 'if/else'語句:
if ($this->validation->run() == FALSE) {
$this->load->view('myform');
} else {
$this->load->view('success');
}
你進行確認測試,並且若是輸入內容不能經過測試的話,就再返回到輸入頁面。(若是你在一個控制器內的一個函數中生成你的視圖, 則使用$this->myfunction 代替$this->load->view('myform')。
若是校驗成功,就生成view("success"),告訴用戶輸入的信息已被接受, 而後給出一個連接讓他進到下一步。
設置表格
錄入信息的表格也要作相應的調整。 每次校驗沒有經過的話,你不但要讓系統返回到錄入界面,並且必須說明哪一項出錯, 以及爲何出錯。 所以你必須在表格的某處給出一個附加信息:
$this->validation->error_string;
這行代碼顯示適當的信息, 避免用戶在那裏犯嘀咕。
你也須要自動地填寫用戶已正確輸入的那些內容,不然,用戶必須再次錄入上一次他們已經正確錄入的信息。
首先,你須要在控制器裏增長更多的代碼。並且是馬上加在校驗規則以後,加入一個數組來存放給用戶的提示信息。 數組的鍵名是你表格中的輸入框名,值是給出的錯誤提示信息:
$fields['url'] = '你的網址';
而後,增長一行代碼:
$this->validation->set_fields($fields);
如今你已經在控制器裏聲明瞭一個存有信息的數組,你只須要在表格內加入顯示它們的代碼。 對於HTML代碼,這會是:
<input type="text" name="url" value="<?php echo $this->validation->url; ?>"/>
或, 若是你正在使用 CI 的表格助手:
$variable .= form_input('url', "$this->valication->url");
若是使用這個表格插入一個新的記錄到數據庫的表中,上面的代碼已經夠用了。若是你正在使用表格更新一個已經輸入過的記錄,當表格第一次顯示時,應該在輸入框中顯示數據庫表中的實際信息,這個時候,它的值應該是從數據庫裏讀回來的(記得前面的例子嗎?咱們把代碼再顯示在這裏:
$this->db->select('id, url, name');
$this->db->where('id','$id');
$sitequery = $this->db->get('sites');
$siterow = $sitequery->row();
echo form_dropdown('url' 、 $urlarray, $siterow->url);
若是你在更新一個現有的記錄時,上一次的錄入內容因爲一個輸入框內容沒有錄入而沒法經過校驗,在從新回到表格以前,你須要在經過校驗的輸入框中填寫用戶剛錄入的信息,而在校驗出錯的輸入框裏再次放入從數據庫表中讀入的信息,不然,你就須要再次錄入已經校驗經過的信息了。
還好,這能夠經過一個簡單的「if/else」語句來實現:
if (isset($_post['url'])) {
$myvalue=$this->validation->url;
} else {
$myvalue=$siterow->url;
}
第一次表格顯示的時候,在$_POST數組中將會沒有內容; 所以你從數據庫的相關表中讀取信息。但當你提交一次之後,$_POAT數組中有數據存在,因此你選擇validation函數中返回的值。
查閱CI用戶手冊,瞭解表格校驗的其它內容,你還能夠作到:
。自動地準備你的數據, 舉例來講, 經過它消除可能產生的跨站腳本攻擊
。編寫你本身的複雜校驗標準,舉例來講, 用戶錄入的值不能已經存在於數據庫中
。編寫你本身的錯誤信息
CI的校驗類很是有用而又功能強大,值得花時間好好研讀並掌握。
摘要
咱們已經學習了CI中生成視圖的方法, 以及它如何讓你建立'迷你-視圖', 你能把視圖嵌套到其它視圖中去。這意謂你能創建共用的HTML header,HTML footer, 實現視圖的重用。
咱們也已經見到 CI 如何幫助你編寫 HTML 錄入表格,經過表格助手函數簡化HTML form的編寫工做。
最後,咱們學習了 CI 的校驗類,這是檢查用戶錄入信息的有用工具。沒有什麼是完美的,可是這個工具的確能阻擊你的用戶錄入垃圾,或企圖進行攻擊。它也使你的網站看起來更加專業,可以有效地捕捉用戶形成的各類輸入錯誤,而不是一味地接受無心義的輸入。
在整個學習過程當中,咱們也再次玩味了MVC的原則, 並且有時稍稍地作一些變通會讓生活變得更容易。 CI 有一種很是有柔性的哲學: 若是要有效率地解決問題,就要學會靈活地使用工具。
javascript