CodeIgniter4 控制器

2020-08-17 15:03 更新

控制器是你整個(gè)應(yīng)用的核心,因?yàn)樗鼈儧Q定了 HTTP 請(qǐng)求將被如何處理。

什么是控制器?

簡(jiǎn)而言之,一個(gè)控制器就是一個(gè)類(lèi)文件,是以一種能夠和 URI 關(guān)聯(lián)在一起的方式來(lái)命名的。

考慮下面的 URI:

example.com/index.php/blog/

上例中,CodeIgniter 將會(huì)嘗試查詢(xún)一個(gè)名為 Blog.php 的控制器并加載它。

當(dāng)控制器的名稱(chēng)和 URI 的第一段匹配上時(shí),它將會(huì)被加載。

讓我們?cè)囋嚳矗篐ello World!

接下來(lái)你會(huì)看到如何創(chuàng)建一個(gè)簡(jiǎn)單的控制器,打開(kāi)你的文本編輯器,新建一個(gè)文件 Blog.php , 然后放入以下代碼:

<?php
class Blog extends \CodeIgniter\Controller
{
        public function index()
        {
                echo 'Hello World!';
        }
}

然后將文件保存到 /application/controllers/ 目錄下。

重要

文件名必須是大寫(xiě)字母開(kāi)頭,如:’Blog.php’ 。

現(xiàn)在使用類(lèi)似下面的 URL 來(lái)訪問(wèn)你的站點(diǎn)::

example.com/index.php/blog

如果一切正常,你將看到::

Hello World!

重要

類(lèi)名必須以大寫(xiě)字母開(kāi)頭。

這是有效的:

<?php
class Blog extends \CodeIgniter\Controller {


}

這是 無(wú)效 的:

<?php
class blog extends \CodeIgniter\Controller {


}

另外,一定要確保你的控制器繼承了父控制器類(lèi),這樣它才能使用父類(lèi)的方法。

方法

上例中,方法名為 index() ?!眎ndex” 方法總是在 URI 的 第二段 為空時(shí)被調(diào)用。 另一種顯示 “Hello World” 消息的方法是:

example.com/index.php/blog/index/

URI 中的第二段用于決定調(diào)用控制器中的哪個(gè)方法。

讓我們?cè)囈幌拢蚰愕目刂破魈砑右粋€(gè)新的方法:

<?php
class Blog extends \CodeIgniter\Controller {


        public function index()
        {
                echo 'Hello World!';
        }


        public function comments()
        {
                echo 'Look at this!';
        }
}

現(xiàn)在,通過(guò)下面的 URL 來(lái)調(diào)用 comments 方法:

example.com/index.php/blog/comments/

你應(yīng)該能看到你的新消息了。

通過(guò) URI 分段向你的方法傳遞參數(shù)

如果你的 URI 多于兩個(gè)段,多余的段將作為參數(shù)傳遞到你的方法中。

例如,假設(shè)你的 URI 是這樣:

example.com/index.php/products/shoes/sandals/123

你的方法將會(huì)收到第三段和第四段兩個(gè)參數(shù)(”sandals” 和 “123”):

<?php
class Products extends \CodeIgniter\Controller {


        public function shoes($sandals, $id)
        {
                echo $sandals;
                echo $id;
        }
}

重要

如果你使用了 URI 路由 ,傳遞到你的方法的參數(shù)將是路由后的參數(shù)。

定義默認(rèn)控制器

CodeIgniter 可以設(shè)置一個(gè)默認(rèn)的控制器,當(dāng) URI 沒(méi)有分段參數(shù)時(shí)加載,例如當(dāng)用戶直接訪問(wèn)你網(wǎng)站的首頁(yè)時(shí)。 打開(kāi) application/config/routes.php 文件,通過(guò)下面的參數(shù)指定一個(gè)默認(rèn)的控制器:

$routes->setDefaultController('Blog');

其中,“Blog”是你想加載的控制器類(lèi)名,如果你現(xiàn)在通過(guò)不帶任何參數(shù)的 index.php 訪問(wèn)你的站點(diǎn),你將看到你的“Hello World”消息。

想要了解更多信息,請(qǐng)參閱 ./source/general/routing.rst 部分文檔。

重映射方法

正如上文所說(shuō),URI 的第二段通常決定控制器的哪個(gè)方法被調(diào)用。CodeIgniter 允許你使用 _remap() 方法來(lái)重寫(xiě)該規(guī)則:

public function _remap()
{
        // Some code here...
}

重要

如果你的控制包含一個(gè) _remap() 方法,那么無(wú)論 URI 中包含什么參數(shù)時(shí)都會(huì)調(diào)用該方法。 它允許你定義你自己的路由規(guī)則,重寫(xiě)默認(rèn)的使用 URI 中的分段來(lái)決定調(diào)用哪個(gè)方法這種行為。

被重寫(xiě)的方法(通常是 URI 的第二段)將被作為參數(shù)傳遞到 _remap() 方法:

public function _remap($method)
{
        if ($method === 'some_method')
        {
                $this->$method();
        }
        else
        {
                $this->default_method();
        }
}

方法名之后的所有其他段將作為 _remap() 方法的第二個(gè)參數(shù),它是可選的。這個(gè)參數(shù)可以使用 PHP 的 call_user_func_array() 函數(shù)來(lái)模擬 CodeIgniter 的默認(rèn)行為。

例如:

public function _remap($method, ...$params)
{
        $method = 'process_'.$method;
        if (method_exists($this, $method))
        {
                return $this->$method(...$params);
        }
        show_404();
}

私有方法

有時(shí)候你可能希望某些方法不能被公開(kāi)訪問(wèn),要實(shí)現(xiàn)這點(diǎn),只要簡(jiǎn)單的將方法聲明為 private 或 protected , 這樣這個(gè)方法就不能被 URL 訪問(wèn)到了。例如,如果你有一個(gè)下面這個(gè)方法:

protected function utility()
{
        // some code
}

使用下面的 URL 嘗試訪問(wèn)它,你會(huì)發(fā)現(xiàn)是無(wú)法訪問(wèn)的:

example.com/index.php/blog/utility/

將控制器放入子目錄中

如果你正在構(gòu)建一個(gè)比較大的應(yīng)用,那么將控制器放到子目錄下進(jìn)行組織可能會(huì)方便一點(diǎn)。CodeIgniter 也可以實(shí)現(xiàn)這一點(diǎn)。

你只需要簡(jiǎn)單的在 application/controllers/ 目錄下創(chuàng)建新的目錄,并將控制器文件放到子目錄下。

注解

當(dāng)使用該功能時(shí),URI 的第一段必須指定目錄,例如,假設(shè)你在如下位置有一個(gè)控制器:


application/controllers/products/Shoes.php


為了調(diào)用該控制器,你的 URI 應(yīng)該像下面這樣:


example.com/index.php/products/shoes/show/123

每個(gè)子目錄包含一個(gè)默認(rèn)控制器,將在 URL 只包含子目錄的時(shí)候被調(diào)用。默認(rèn)控制器在 application/Config/Routes.php 中定義。

你也可以使用 CodeIgniter 的 ./source/general/routing.rst 功能來(lái)重定向 URI。

構(gòu)造函數(shù)

如果你打算在你的控制器中使用構(gòu)造函數(shù),你 必須 將下面這行代碼放在里面::

parent::__construct(…$params);

原因是你的構(gòu)造函數(shù)將會(huì)覆蓋父類(lèi)的構(gòu)造函數(shù),所以我們要手工的調(diào)用它。

例如:

<?php
class Blog extends \CodeIgniter\Controller
{
        public function __construct(...$params)
        {
                parent::__construct(...$params);


                // Your own constructor code
        }
}

如果你需要在你的類(lèi)被初始化時(shí)設(shè)置一些默認(rèn)值,或者進(jìn)行一些默認(rèn)處理,構(gòu)造函數(shù)將很有用。 構(gòu)造函數(shù)沒(méi)有返回值,但是可以執(zhí)行一些默認(rèn)操作。

包含屬性

你創(chuàng)建的每一個(gè) controller 都應(yīng)該繼承 CodeIgniter\Controller 類(lèi)。這個(gè)類(lèi)提供了適合所有控制器的幾個(gè)屬性。

Request 對(duì)象

$this->request 作為應(yīng)用程序的主要屬性 ./source/libraries/request.rst 是可以一直被使用的類(lèi)屬性。

Response 對(duì)象

$this->response 作為應(yīng)用程序的主要屬性 ./source/libraries/response.rst 是可以一直被使用的類(lèi)屬性。

Logger 對(duì)象

$this->logger 類(lèi)實(shí)例 ./source/general/logging.rst 是可以一直被使用的類(lèi)屬性。

forceHTTPS

一種強(qiáng)制通過(guò) HTTPS 訪問(wèn)方法的便捷方法,在所有控制器中都是可用的:

if (! $this->request->isSecure())
{
        $this->forceHTTPS();
}

默認(rèn)情況下,在支持 HTTP 嚴(yán)格傳輸安全報(bào)頭的現(xiàn)代瀏覽器中,此調(diào)用應(yīng)強(qiáng)制瀏覽器將非 HTTPS 調(diào)用轉(zhuǎn)換為一年的 HTTPS 調(diào)用。你可以通過(guò)將持續(xù)時(shí)間(以秒為單位)作為第一個(gè)參數(shù)來(lái)修改。

if (! $this->request->isSecure())
{
        $this->forceHTTPS(31536000);    // one year
}

注解

你可以使用更多全局變量和函數(shù) ./source/general/common_functions.rst ,包括 年、月等等。

輔助函數(shù)

你可以定義一個(gè)輔助文件數(shù)組作為類(lèi)屬性。每當(dāng)控制器被加載時(shí), 這些輔助文件將自動(dòng)加載到內(nèi)存中,這樣就可以在控制器的任何地方使用它們的方法。:

class MyController extends \CodeIgniter\Controller
{
        protected $helpers = ['url', 'form'];
}

驗(yàn)證 $_POST 數(shù)據(jù)

控制器還提供了一個(gè)簡(jiǎn)單方便的方法來(lái)驗(yàn)證 $_POST 數(shù)據(jù),將一組規(guī)則作為第一個(gè)參數(shù)進(jìn)行驗(yàn)證,如果驗(yàn)證不通過(guò),可以選擇顯示一組自定義錯(cuò)誤消息。你可以通過(guò) $this->request 這個(gè)用法獲取 POST 數(shù)據(jù)。 Validation Library docs 是有關(guān)規(guī)則和消息數(shù)組的格式以及可用規(guī)則的詳細(xì)信息。

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...
}

如果你覺(jué)得在配置文件中保存規(guī)則更簡(jiǎn)單,你可以通過(guò)在 Config\Validation.php 中定義代替 $rules 數(shù)組

public function updateUser(int $userID)
{
    if (! $this->validate('userRules'))
    {
        return view('users/update', [
            'errors' => $this->errors
        ]);
    }


    // do something here if successful...
}

注解

驗(yàn)證也可以在模型中自動(dòng)處理。你可以在任何地方處理,你會(huì)發(fā)現(xiàn)控制器中的一些情況比模型簡(jiǎn)單,反之亦然。

就這樣了!

OK,總的來(lái)說(shuō),這就是關(guān)于控制器的所有內(nèi)容了。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)