控制器?
控制器是你整個應用的核心,因為它們決定了 HTTP 請求將被如何處理。
什么是控制器??
簡而言之,一個控制器就是一個類文件,是以一種能夠和 URI 關聯在一起的方式來命名的。
考慮下面的 URI:
example.com/index.php/blog/
上例中,CodeIgniter 將會嘗試查詢一個名為 Blog.php 的控制器并加載它。
當控制器的名稱和 URI 的第一段匹配上時,它將會被加載。
讓我們試試看:Hello World!?
接下來你會看到如何創建一個簡單的控制器,打開你的文本編輯器,新建一個文件 Blog.php , 然后放入以下代碼:
<?php
class Blog extends \CodeIgniter\Controller
{
public function index()
{
echo 'Hello World!';
}
}
然后將文件保存到 /application/controllers/ 目錄下。
重要
文件名必須是大寫字母開頭,如:’Blog.php’ 。
現在使用類似下面的 URL 來訪問你的站點::
example.com/index.php/blog
如果一切正常,你將看到::
Hello World!
重要
類名必須以大寫字母開頭。
這是有效的:
<?php
class Blog extends \CodeIgniter\Controller {
}
這是 無效 的:
<?php
class blog extends \CodeIgniter\Controller {
}
另外,一定要確保你的控制器繼承了父控制器類,這樣它才能使用父類的方法。
方法?
上例中,方法名為 index()
?!眎ndex” 方法總是在 URI 的 第二段 為空時被調用。 另一種顯示 “Hello World” 消息的方法是:
example.com/index.php/blog/index/
URI 中的第二段用于決定調用控制器中的哪個方法。
讓我們試一下,向你的控制器添加一個新的方法:
<?php
class Blog extends \CodeIgniter\Controller {
public function index()
{
echo 'Hello World!';
}
public function comments()
{
echo 'Look at this!';
}
}
現在,通過下面的 URL 來調用 comments 方法:
example.com/index.php/blog/comments/
你應該能看到你的新消息了。
通過 URI 分段向你的方法傳遞參數?
如果你的 URI 多于兩個段,多余的段將作為參數傳遞到你的方法中。
例如,假設你的 URI 是這樣:
example.com/index.php/products/shoes/sandals/123
你的方法將會收到第三段和第四段兩個參數(”sandals” 和 “123”):
<?php
class Products extends \CodeIgniter\Controller {
public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}
重要
如果你使用了 URI 路由 ,傳遞到你的方法的參數將是路由后的參數。
定義默認控制器?
CodeIgniter 可以設置一個默認的控制器,當 URI 沒有分段參數時加載,例如當用戶直接訪問你網站的首頁時。 打開 application/config/routes.php 文件,通過下面的參數指定一個默認的控制器:
$routes->setDefaultController('Blog');
其中,“Blog”是你想加載的控制器類名,如果你現在通過不帶任何參數的 index.php 訪問你的站點,你將看到你的“Hello World”消息。
想要了解更多信息,請參閱 ./source/general/routing.rst 部分文檔。
重映射方法?
正如上文所說,URI 的第二段通常決定控制器的哪個方法被調用。CodeIgniter 允許你使用 _remap()
方法來重寫該規則:
public function _remap()
{
// Some code here...
}
重要
如果你的控制包含一個 _remap() 方法,那么無論 URI 中包含什么參數時都會調用該方法。 它允許你定義你自己的路由規則,重寫默認的使用 URI 中的分段來決定調用哪個方法這種行為。
被重寫的方法(通常是 URI 的第二段)將被作為參數傳遞到 _remap()
方法:
public function _remap($method)
{
if ($method === 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
方法名之后的所有其他段將作為 _remap()
方法的第二個參數,它是可選的。這個參數可以使用 PHP 的 call_user_func_array() 函數來模擬 CodeIgniter 的默認行為。
例如:
public function _remap($method, ...$params)
{
$method = 'process_'.$method;
if (method_exists($this, $method))
{
return $this->$method(...$params);
}
show_404();
}
私有方法?
有時候你可能希望某些方法不能被公開訪問,要實現這點,只要簡單的將方法聲明為 private 或 protected , 這樣這個方法就不能被 URL 訪問到了。例如,如果你有一個下面這個方法:
protected function utility()
{
// some code
}
使用下面的 URL 嘗試訪問它,你會發現是無法訪問的:
example.com/index.php/blog/utility/
將控制器放入子目錄中?
如果你正在構建一個比較大的應用,那么將控制器放到子目錄下進行組織可能會方便一點。CodeIgniter 也可以實現這一點。
你只需要簡單的在 application/controllers/ 目錄下創建新的目錄,并將控制器文件放到子目錄下。
注解
當使用該功能時,URI 的第一段必須指定目錄,例如,假設你在如下位置有一個控制器:
application/controllers/products/Shoes.php
為了調用該控制器,你的 URI 應該像下面這樣:
example.com/index.php/products/shoes/show/123
每個子目錄包含一個默認控制器,將在 URL 只包含子目錄的時候被調用。默認控制器在 application/Config/Routes.php 中定義。
你也可以使用 CodeIgniter 的 ./source/general/routing.rst 功能來重定向 URI。
構造函數?
如果你打算在你的控制器中使用構造函數,你 必須 將下面這行代碼放在里面::
parent::__construct(…$params);
原因是你的構造函數將會覆蓋父類的構造函數,所以我們要手工的調用它。
例如:
<?php
class Blog extends \CodeIgniter\Controller
{
public function __construct(...$params)
{
parent::__construct(...$params);
// Your own constructor code
}
}
如果你需要在你的類被初始化時設置一些默認值,或者進行一些默認處理,構造函數將很有用。 構造函數沒有返回值,但是可以執行一些默認操作。
包含屬性?
你創建的每一個 controller 都應該繼承 CodeIgniter\Controller
類。這個類提供了適合所有控制器的幾個屬性。
Request 對象?
$this->request
作為應用程序的主要屬性 ./source/libraries/request.rst 是可以一直被使用的類屬性。
Response 對象?
$this->response
作為應用程序的主要屬性 ./source/libraries/response.rst 是可以一直被使用的類屬性。
forceHTTPS?
一種強制通過 HTTPS 訪問方法的便捷方法,在所有控制器中都是可用的:
if (! $this->request->isSecure())
{
$this->forceHTTPS();
}
默認情況下,在支持 HTTP 嚴格傳輸安全報頭的現代瀏覽器中,此調用應強制瀏覽器將非 HTTPS 調用轉換為一年的 HTTPS 調用。你可以通過將持續時間(以秒為單位)作為第一個參數來修改。
if (! $this->request->isSecure())
{
$this->forceHTTPS(31536000); // one year
}
注解
你可以使用更多全局變量和函數 ./source/general/common_functions.rst ,包括 年、月等等。
驗證 $_POST 數據?
控制器還提供了一個簡單方便的方法來驗證 $_POST 數據,將一組規則作為第一個參數進行驗證,如果驗證不通過,可以選擇顯示一組自定義錯誤消息。你可以通過 $this->request 這個用法獲取 POST 數據。 Validation Library docs 是有關規則和消息數組的格式以及可用規則的詳細信息。
public function updateUser(int $userID)
{
if (! $this->validate([
'email' => "required|is_unique[users.email,id,{$userID}]",
'name' => 'required|alpha_numeric_spaces'
]))
{
return view('users/update', [
'errors' => $this->errors
]);
}
// do something here if successful...
}
如果你覺得在配置文件中保存規則更簡單,你可以通過在 Config\Validation.php
中定義代替 $rules 數組
public function updateUser(int $userID)
{
if (! $this->validate('userRules'))
{
return view('users/update', [
'errors' => $this->errors
]);
}
// do something here if successful...
}
注解
驗證也可以在模型中自動處理。你可以在任何地方處理,你會發現控制器中的一些情況比模型簡單,反之亦然。