代碼模塊?

CodeIgniter 支持代碼模塊化組合,以便于你構(gòu)建可重用的代碼。模塊通常來(lái)說(shuō)是以一個(gè)特定主題為中心而構(gòu)建的,并可被認(rèn)為是在大型的程序中的一系列微型程序。 我們支持框架中所有標(biāo)準(zhǔn)的文件類(lèi)型,例如控制器,模型,視圖,配置文件,輔助函數(shù),語(yǔ)言文件等。模塊可能包含著或多或少的你所需要的以上這些類(lèi)型中。

命名空間?

CodeIgniter所使用的模塊功能的核心組件來(lái)自于 與PSR4相適應(yīng)的自動(dòng)加載 。 雖然所有的代碼都可以使用PSR4的自動(dòng)加載和命名空間,最主要的充分使用模塊優(yōu)勢(shì)的方式還是為你的代碼加上命名空間,并將其添加到 app/Config/Autoload.php 中,在 psr4 這節(jié)中。

舉例而言,比如我們需要維護(hù)一個(gè)在應(yīng)用間復(fù)用的簡(jiǎn)單的博客模塊。我們可能會(huì)創(chuàng)建一個(gè)帶有公司名(比如acme)的文件夾來(lái)保存所有的模塊。 我們可能會(huì)將其置于我們的 application 目錄旁邊,在主項(xiàng)目目錄下:

/acme        // 新的模塊目錄
/application
/public
/system
/tests
/writable

打開(kāi) app/Config/Autoload.php 并將 Acme 命名空間加入到 psr4 數(shù)組成員中:

$psr4 = [
    'Config'        => APPPATH . 'Config',
    APP_NAMESPACE   => APPPATH,                // 自定義命名空間
    'App'           => APPPATH,                // 確保篩選器等組件可找到,
    'Acme'          => ROOTPATH.'acme'
];

當(dāng)我們?cè)O(shè)置完以上流程后,就可以通過(guò) Acme 命名空間來(lái)訪問(wèn) acme 目錄下的文件夾內(nèi)容。這已經(jīng)完成了80%的模塊工作所需要的內(nèi)容, 所以你可以通過(guò)熟悉命名空間來(lái)適應(yīng)這種使用方式。這樣多種文件類(lèi)型將會(huì)被自動(dòng)掃描并在整個(gè)定義的命名空間中使用——這也是使用模塊的關(guān)鍵。

在模塊中的常見(jiàn)目錄結(jié)構(gòu)和主程序目錄類(lèi)似:

/acme
    /Blog
        /Config
        /Controllers
        /Database
            /Migrations
            /Seeds
        /Helpers
        /Language
            /en
        /Libraries
        /Models
        /Views

當(dāng)然了,不強(qiáng)制使用這樣的目錄結(jié)構(gòu),你也可以自定義目錄結(jié)構(gòu)來(lái)更好地符合你的模塊要求,去掉那些你不需要的目錄并增加一些新的目錄,例如實(shí)體(Entites),接口(Interfaces),倉(cāng)庫(kù)(Repository)等。

自動(dòng)發(fā)現(xiàn)?

很多情況下,你需要指名你所需要包含進(jìn)來(lái)的文件的命名空間全稱(chēng),但是CodeIgniter可以通過(guò)配置自動(dòng)發(fā)現(xiàn)的文件類(lèi)型,來(lái)將模塊更方便地整合進(jìn)你的項(xiàng)目中:

這些是在 app/Config/Modules.php 文件中配置的。

自動(dòng)發(fā)現(xiàn)系統(tǒng)通過(guò)掃描所有在 Config/Autoload.php 中定義的PSR4類(lèi)型的命名空間來(lái)實(shí)現(xiàn)對(duì)于目錄/文件的識(shí)別。

To make auto-discovery work for our Blog namespace, we need to make one small adjustment. Acme needs to be changed to Acme\Blog because each “module” within the namespace needs to be fully defined. Once your module folder path is defined, the discovery process would look for discoverable items on that path and should, for example, find the routes file at /acme/Blog/Config/Routes.php.

開(kāi)啟/關(guān)閉自動(dòng)發(fā)現(xiàn)?

你可以開(kāi)啟或關(guān)閉所有的系統(tǒng)中的自動(dòng)發(fā)現(xiàn),通過(guò) $enabled 類(lèi)變量。False的話就會(huì)關(guān)閉所有的自動(dòng)發(fā)現(xiàn),優(yōu)化性能,但卻會(huì)讓你的模塊可用性相對(duì)下降。

明確目錄項(xiàng)目?

通過(guò) $activeExplorers 選項(xiàng),你可以明確哪些項(xiàng)目是自動(dòng)發(fā)現(xiàn)的。如果這個(gè)項(xiàng)目不存在,就不會(huì)對(duì)它進(jìn)行自動(dòng)發(fā)現(xiàn)流程,而數(shù)組中的其他成員仍舊會(huì)被自動(dòng)發(fā)現(xiàn)。

自動(dòng)發(fā)現(xiàn)與Composer?

通過(guò)Composer安裝的包將會(huì)默認(rèn)被自動(dòng)發(fā)現(xiàn)。這只需要Composer識(shí)別所需要加載的命名空間是符合PSR4規(guī)范的命名空間,PSR0類(lèi)型的命名空間將不會(huì)被發(fā)現(xiàn)。

如果在定位文件時(shí),你不想掃描所有Composer已識(shí)別的的目錄,可以通過(guò)編輯 Config\Modules.php 中的 $discoverInComposer 變量來(lái)關(guān)閉這一功能:

public $discoverInComposer = false;

處理文件?

這節(jié)將會(huì)詳細(xì)介紹每種文件類(lèi)型(控制器,視圖,語(yǔ)言文件等)以及在模塊中如果使用它們。其中的某些信息在用戶手冊(cè)中將會(huì)更為詳細(xì)地描述,不過(guò)在這里重新介紹一下以便了解全局的情況。

路由?

默認(rèn)情況下, 路由 將會(huì)在模塊內(nèi)部自動(dòng)掃描,而這一特性可在 Modules 配置文件中被關(guān)閉,如上所述。

注解

由于在當(dāng)前域內(nèi)包含了路由文件, $routes 實(shí)例已經(jīng)被定義了,所以當(dāng)你嘗試重新定義類(lèi)的時(shí)候可能會(huì)引起錯(cuò)誤。

控制器?

在主 app/Controller 目錄下定義的控制器不會(huì)自動(dòng)被URI路由自動(dòng)調(diào)用,所以需要在路由文件內(nèi)部手動(dòng)聲明:

// Routes.php
$routes->get('blog', 'Acme\Blog\Controllers\Blog::index');

為了減少不必要的輸入, group 路由特性(譯者注: 分組路由 </incoming/routing#分組路由> )是一個(gè)不錯(cuò)的選擇:

$routes->group('blog', ['namespace' => 'Acme\Blog\Controllers'], function($routes)
{
    $routes->get('/', 'Blog::index');
});

配置文件?

No special change is needed when working with configuration files. These are still namespaced classes and loaded with the new command:

$config = new \Acme\Blog\Config\Blog();

Config files are automatically discovered whenever using the config() function that is always available.

遷移?

遷移文件將通過(guò)定義的命名空間自動(dòng)發(fā)現(xiàn)。所有命名空間里找到的遷移每次都會(huì)被自動(dòng)運(yùn)行。

種子?

種子文件可在CLI或其他種子文件里使用,只要提供了完整的命名空間名。如果通過(guò)CLI調(diào)用,就需要提供雙反斜杠定義的類(lèi)名格式(\):

> php public/index.php migrations seed Acme\\Blog\\Database\\Seeds\\TestPostSeeder

輔助函數(shù)?

當(dāng)使用 helper() 方法時(shí),輔助函數(shù)將會(huì)通過(guò)定義的命名空間自動(dòng)定位。只要它存在于 Helpers 命名空間目錄下:

helper('blog');

語(yǔ)言文件?

當(dāng)使用 lang() 方法時(shí),語(yǔ)言文件是通過(guò)定義的命名空間來(lái)自動(dòng)定位的。只要這個(gè)文件是遵循主程序目錄一樣的目錄結(jié)構(gòu)來(lái)放置的。

庫(kù)?

庫(kù)總是通過(guò)完全命名空間化的類(lèi)名進(jìn)行實(shí)例化,所以不需要額外的操作:

$lib = new \Acme\Blog\Libraries\BlogLib();

模型?

模型總是通過(guò)完全命名空間化的類(lèi)名進(jìn)行實(shí)例化,所以不需要額外的操作:

$model = new \Acme\Blog\Models\PostModel();

視圖?

視圖文件可通過(guò) 視圖 文檔中所述的類(lèi)命名空間進(jìn)行加載:

echo view('Acme\Blog\Views\index');