控制器(Controllers)
控制器(Controllers)是你的 application 的核心動力,決定了如何處理 HTTP 所發出的要求。
- 什麼是控制器(Controller)呢?
- 我們的第一個程式: Hello World!
- 函數(Functions)
- 傳遞 URL 段落到你的函數裡
- 定義預設的控制器
- 重新對映函數呼叫
- 控制輸出資料
- 私有函數
- 把控制器收納進子目錄裡頭
- 類別建構子(Class Constructors)
- 保留函數名稱
什麼是控制器(Controller)呢?
控制器(Controller)簡單來說就是 class 檔案,用來處理 URI。
看看這個 URI:
example.com/index.php/blog/
在上例中,CodeIgniter 會嘗試在找一個 blog.php 的控制器,並且找到後載入進來。
當控制器的名稱在 URI 中的第一段可以符合的話,它就會被載入。
我們的第一個程式: Hello World!
先建立一個簡單的控制器(controller),用你的編輯器建立一個 blog.php 的檔案,把下列的程式碼塞進去:
存到 application/controllers/ 目錄底下。
現在打開像是底下的 URL 位置:
example.com/index.php/blog/
如果沒什麼出錯的話,你應該會看到 Hello World!。
注意: Class 命名必須要字首大寫,換句話說,這樣是可以的命名:
<?php
class Blog extends CI_Controller {
}
?>
這個就是 不被接受的命名:
<?php
class blog extends CI_Controller {
}
?>
還有,請務必確定你的控制器是從母控制器(parent controller) 擴充出來,這樣才可以繼承母控制器的所有函數。
函數(Functions)
看看上面例子的函數名稱,它叫作是index()。這個 "index" 函數通常是預設載入, 假如 URI 的 第二個分段(second segment) 是 empty 的話。另一個秀出 "Hello World" 的方法,則是這樣:
example.com/index.php/blog/index/
URI 的第二個分段,決定了控制器裡頭的那一個函數得被呼叫出來。
接下來在試試看,新增一個函數到你的控制器裡頭:
現在載入底下的 URL 來看看這個 comment 函數:
example.com/index.php/blog/comments/
你應該會看到你的新的訊息!
傳遞 URL 段落到你的函數裡
假如你的 URI 包含超過兩個分段的話,他們會把這個當成是參數傳遞到你的函數裡頭。
舉例來說,如果你有個像這樣的 URL :
example.com/index.php/products/shoes/sandals/123
你的函數會收到第三跟第四的 URI 分段的內容,也就是會收到 "sandals" 以及 "123" 的參數:
<?php
class Products extends CI_Controller {
public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}
?>
非常重要: 如果你使用 URI Routing 的功能,收到的內容則會是被 re-routed 過後的那個。
定義預設的控制器
CodeIgniter 可以修改預設載入的控制器,如要設定預設的控制器,請開啟 application/config/routes.php 的檔案,然後設定成底下的變數:
$route['default_controller'] = 'Blog';
這邊的 Blog 是在控制器類別裡頭,你所想要使用的名稱。修改完成後,不需要給予任何 URI 分段內容的預設情況之下,就可以看到 Hello World 的訊息了。
重新對映函數呼叫
如上頭所描述,在第二個URI分段的名稱,通常是決定那個控制器(controller)裡頭那個函數(function)要被呼叫。不過,CodeIgniter 也可以允許你用 _remap() 函數來把它來改寫成:
public function _remap()
{
// Some code here...
}
非常重要: 如果你的控制器裡頭有個 _remap() 函數的話,那麼它會 總是 不理會你的 URI 內容是什麼東西。也就是說,這個方式會改寫掉原本函數呼叫的規則,並且允許使用你自己定義的函數路由規則(function routing rules)。
改寫函數(通常是在URI的第二個區段)將會被當成是參數傳入_remap()函數:
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
Any extra segments after the method name are passed into _remap() as an optional second parameter. This array can be used in combination with PHP's call_user_func_array to emulate CodeIgniter's default behavior.
public function _remap($method, $params = array())
{
$method = 'process_'.$method;
if (method_exists($this, $method))
{
return call_user_func_array(array($this, $method), $params);
}
show_404();
}
輸出處理
CodeIgniter 有個 output 類別會自動處理最後給瀏覽器的資料。更多詳細的資訊可以在 檢視(Views) 以及 Output 類別 查看。某些時候,你也許會想要把最終的資料進行後續處理(post-process),然後在把處理好的資料送回給瀏覽器。CodeIgniter 可以你新增一個 _output() 到控制器裡頭,來負責接收最終的的輸出資料。
非常重要: 若你的控制器內含名為 _output() 的函數,它會 總是 被 output 類別所呼叫,而不是直接傳回最終資料。函數的第一個參數包含最終的輸出。
這裡有個參考範例:
public function _output($output)
{
echo $output;
}
Please note that your _output() function will receive the data in its finalized state. Benchmark and memory usage data will be rendered,
cache files written (if you have caching enabled), and headers will be sent (if you use that feature)
before it is handed off to the _output() function.
To have your controller's output cached properly, its _output() method can use:
if ($this->output->cache_expiration > 0)
If you are using this feature the page execution timer and memory usage stats might not be perfectly accurate
since they will not take into acccount any further processing you do. For an alternate way to control output before any of the final processing is done, please see
the available methods in the Output Class.
{
$this->output->_write_cache($output);
}
私有函數
有時候,你會想要把某些函數隱藏起來,不讓它可以被公開存取。要把函數隱藏起來的話,只要在函數前加上個底線,然後他就不會被送給 URL 呼叫了。舉例來說,你有個像這個樣的函數:
private function _utility()
{
// some code
}
試試看讀取像底下的 URL,應該是不會動的:
example.com/index.php/blog/_utility/
把控制器收納進子目錄裡頭
如果你正在開發大型的 application 的話,你想如果可以把一些控制器,規類到子目錄裡頭會是相當方便的。CodeIgniter 可以讓你這樣做。
只要在 application/controllers 裡頭新增子目錄,然後把你的控制器放進去即可。
注意: 如果要使用這個功能的話,URI 的第一個分段必須指定到目錄去。舉例來說,假設你有個控制器在這個:
application/controllers/products/shoes.php
你的 URL 會看起來像底下這樣,如果你去呼叫以上的控制器的話:
example.com/index.php/products/shoes/show/123
你的兩個子目錄中應該包含預設的控制器,當 URL 只有子目錄時可以被呼叫。 在 application/config/routes.php 中,可以替你的預設控制器取個你喜歡的名字。
CodeIgniter 可以讓你對映(remap)你的 URIs,只要利用 URI Routing 即可達成。
類別建構子(Class Constructors)
若打算在控制器使用建構子的話,你必須 換成底下的那行程式碼:
parent::__construct();
這一行程式碼一定需要的原因,是因為你的 local 建構子會被覆蓋成 parent 控制器類別,所以我們需要以手動方式去呼叫它
<?php
class Blog extends CI_Controller {
public function __construct()
{
parent::__construct();
// Your own constructor code
}
}
?>
如果你的 class 是 instantiated 需要設定些預設值或是跑一些程式,建構子(Constructor)相當實用。建構子無法回傳數值,但是他們可以做一些預設工作。
保留函數名稱
自從你的控制器類別可以擴充 application controller 以來,你必須要格外小心的替你的函數命名,好讓你的類別呼叫使用,否則會發生你的 local 函數把別的函數被覆蓋掉的情況。請看保留字 的列表。
說完了!
這些就是控制器(controllers)最核心的部份。