CodeIgniter 控制器

2018-07-21 15:37 更新

控制器

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

目錄

什么是控制器?

簡單來說,控制器就是一個類文件,它的命名和 URI 有著一定的聯(lián)系。

考慮下面的 URL

example.com/index.php/blog/

上例中,CodeIgniter 將會嘗試查詢一個名為 Blog.php 的控制器并加載它。

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

讓我們試試看:Hello World!

接下來你會看到如何創(chuàng)建一個簡單的控制器,打開你的文本編輯器,新建一個文件 Blog.php , 然后放入以下代碼:

<?php
class Blog extends CI_Controller {

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

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

重要
文件名必須是大寫字母開頭,如:'Blog.php' 。

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

example.com/index.php/blog/

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

Hello World!

重要
類名必須以大寫字母開頭。

這是有效的:

<?php
class Blog extends CI_Controller {

}

這是無效的:

<?php
class blog extends CI_Controller {

}

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

方法

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

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

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

讓我們試一下,向你的控制器添加一個新的方法:

<?php
class Blog extends CI_Controller {

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

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

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

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

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

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

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

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

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

你的方法將會收到第三段和第四段兩個參數(shù)("sandals" 和 "123"):

<?php
class Products extends CI_Controller {

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

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

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

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

$route['default_controller'] = 'blog';

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

重映射方法

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

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

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

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

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

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

例如:

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 有一個輸出類,它可以自動的將最終數(shù)據(jù)發(fā)送到你的瀏覽器。 更多信息可以閱讀 視圖 和 輸出類 頁面。但是,有時候, 你可能希望對最終的數(shù)據(jù)進(jìn)行某種方式的后處理,然后你自己手工發(fā)送到瀏覽器。CodeIgniter 允許你向你的控制器中添加一個 _output() 方法,該方法可以接受最終的輸出數(shù)據(jù)。

重要
如果你的控制器含有一個 _output() 方法,輸出類將會調(diào)用該方法來顯示數(shù)據(jù), 而不是直接顯示數(shù)據(jù)。該方法的第一個參數(shù)包含了最終輸出的數(shù)據(jù)。

這里是個例子:

public function _output($output)
{
    echo $output;
}

注解
請注意,當(dāng)數(shù)據(jù)傳到 _output() 方法時,數(shù)據(jù)已經(jīng)是最終狀態(tài)。這時基準(zhǔn)測試和計(jì)算內(nèi)存占用都已經(jīng)完成, 緩存文件也已經(jīng)寫到文件(如果你開啟緩存的話),HTTP 頭也已經(jīng)發(fā)送(如果用到了該 特性)。

為了使你的控制器能正確處理緩存,_output() 可以這樣寫:

if ($this->output->cache_expiration > 0)
{
    $this->output->_write_cache($output);
}

如果你在使用 _output() 時,希望獲取頁面執(zhí)行時間和內(nèi)存占用情況,結(jié)果可能會不準(zhǔn)確, 因?yàn)椴]有統(tǒng)計(jì)你后加的處理代碼。另一個可選的方法是在所有最終輸出 之前 來進(jìn)行處理, 請參閱 輸出類 。

私有方法

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

private function _utility()
{
    // some code
}

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

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

注解
為了向后兼容原有的功能,在方法名前加上一個下劃線前綴也可以讓該方法無法訪問。

將控制器放入子目錄中

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

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

注解

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

application/controllers/products/Shoes.php

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

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

每個子目錄下都應(yīng)該包含一個默認(rèn)控制器,這樣當(dāng) URL 中只有子目錄路徑時將會調(diào)用它。你可以在 application/config/routes.php 文件中配置默認(rèn)控制器。

你也可以使用 CodeIgniter 的 URI 路由 功能 來重定向 URI 。

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

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

parent::__construct();

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

例如:

<?php
class Blog extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        // Your own constructor code
    }
}

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

保留方法名

因?yàn)槟愕目刂破鲗⒗^承主程序的控制器,在新建方法時你必須要小心不要使用和父類一樣的方法名, 要不然你的方法將覆蓋它們,參見 保留名稱 。

重要
另外,你也絕對不要新建一個和類名稱一樣的方法。如果你這樣做了,而且你的控制器 又沒有一個 __construct() 構(gòu)造函數(shù),那么這個和類名同名的方法 Index::index() 將會作為類的構(gòu)造函數(shù)被執(zhí)行!這個是 PHP4 的向前兼容的一個特性。

就這樣了!

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號