CodeIgniter4 利用配置文件開始工作

2020-08-17 14:32 更新

每一個(gè)項(xiàng)目,都需要一種方法來定義不同的全局配置項(xiàng),而這通常是借助配置文件來實(shí)現(xiàn)的。 而配置文件,一般來說,是通過聲明一個(gè)將所有的配置項(xiàng)作為公開屬性的類,來實(shí)現(xiàn)這一配置過程的。 不同于許多其他的框架,在CI4中,不需要訪問某個(gè)具體的類來修改我們的配置項(xiàng)信息。 取而代之的是,我們僅僅需要?jiǎng)?chuàng)建一個(gè)配置類的實(shí)例,從而輕而易舉的實(shí)現(xiàn)配置流程。

訪問配置文件

我們可以通過創(chuàng)建一個(gè)新的配置類實(shí)例或者使用config函數(shù),來訪問類中的配置項(xiàng)。 配置類中所有的這些屬性都是公開的,故而可以如調(diào)用其他屬性一樣調(diào)用相應(yīng)的配置項(xiàng):

  // 手動(dòng)創(chuàng)建一個(gè)新的配置類實(shí)例
  $config = new \Config\Pager();
  // 使用config函數(shù)創(chuàng)建一個(gè)新的配置類實(shí)例
  $config = config( 'Pager', false );
  // 通過config函數(shù)使用共享的配置類實(shí)例
  $config = config( 'Pager' );
  // 通過namespace(命名空間)使用配置類
  $config = config( 'Config\\Pager' );
  // 以類屬性成員的形式使用配置
  $pageSize = $config->perPage;

若沒有給定namespace(命名空間),框架會(huì)在所有可用的、已被定義的命名空間中搜尋所需的文件,就如同 /app/Config/ 一樣。 所以Codeigniter里所有的配置文件都應(yīng)當(dāng)被放置在 Config 這一命名空間下。 由于框架可以確切地了解配置文件所在目錄的的位置,從而不必掃描文件系統(tǒng)中的不同區(qū)域;故而在我們的項(xiàng)目中,使用命名空間將會(huì)有效地提升性能。

我們也可以通過使用一個(gè)不同的命名空間,從而在服務(wù)器的任意位置上部署所需的配置文件。 這一舉措可以讓我們將生產(chǎn)環(huán)境的服務(wù)器中的配置文件移動(dòng)到一個(gè)不能通過Web訪問的位置;而在開發(fā)環(huán)境中,將其放置在 /app 目錄下以便訪問。

創(chuàng)建配置文件

當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)新的配置文件時(shí),需要在指定位置創(chuàng)建一個(gè)新的文件,例如在默認(rèn)的 /app/Config 目錄下。然后創(chuàng)建一個(gè)帶有公開屬性的類,從而放置相應(yīng)的配置信息:

  <?php namespace Config;
  use CodeIgniter\Config\BaseConfig;
  class App extends BaseConfig
  {
      public $siteName  = 'My Great Site';
      public $siteEmail = 'webmaster@example.com';
  }

這個(gè)類應(yīng)當(dāng)繼承 \CodeIgniter\Config\BaseConfig 從而保證框架可以得到具體環(huán)境下的配置信息。

針對(duì)不同的環(huán)境

由于我們的站點(diǎn)將會(huì)在不同的環(huán)境中運(yùn)行,例如開發(fā)者的本地機(jī)器上,或是用于部署的遠(yuǎn)端服務(wù)器上,我們可以基于環(huán)境來修改配置信息。 在這基礎(chǔ)上,我們將能夠根據(jù)站點(diǎn)所運(yùn)行的服務(wù)器,來使用不同的配置信息。這些包括并不限于數(shù)據(jù)庫配置信息,API認(rèn)證信息,以及其他的根據(jù)部署環(huán)境而改變的配置信息。

我們可以將這些值保存在根目錄下的一個(gè) .env 文件中,就如system和application目錄一樣。這個(gè)文件就如一個(gè) “.ini” 配置文件一樣,由許多對(duì)被等號(hào)分割的鍵/值對(duì)所組成:

  S3_BUCKET="dotenv"
  SECRET_KEY="super_secret_key"

當(dāng)這些變量已經(jīng)在環(huán)境中被定義時(shí),它們將不會(huì)被重復(fù)定義。

重要

確保 .env 類型的文件已經(jīng)添加到 .gitignore (或是相同類型的其他版本控制系統(tǒng))中,從而保證在代碼中不會(huì)被上傳。 若這一舉措未能成功,則可能會(huì)導(dǎo)致該目錄中的相關(guān)敏感認(rèn)證信息能夠被任何人隨意訪問。

創(chuàng)建一個(gè)類似于 .env.example 的,其中包含了所有我們的項(xiàng)目所需的,僅設(shè)置了配置項(xiàng)的空值或默認(rèn)值的模板文件,是一個(gè)不錯(cuò)的方法。 在不同的環(huán)境里,我們可以把這個(gè)文件復(fù)制到 .env 目錄下并填充這個(gè)環(huán)境相對(duì)應(yīng)的配置項(xiàng)的值。

當(dāng)應(yīng)用開始運(yùn)行時(shí),這個(gè)文件將會(huì)被自動(dòng)加載,同時(shí)這些變量也會(huì)被運(yùn)行環(huán)境所調(diào)用——這一過程適用于所有環(huán)境的部署。 在這之后,這些變量將通過 getenv(), $_SERVER, and $_ENV 的方式被調(diào)用。在這三者中, getenv() 方法由于其大小寫不敏感而被推薦使用:

  $s3_bucket = getenv('S3_BUCKET');
  $s3_bucket = $_ENV['S3_BUCKET'];
  $s3_bucket = $_SERVER['S3_BUCKET'];

注意

如果你正在使用Apache服務(wù)器,CI_ENVIRONMENT 可以被設(shè)置于 public/.htaccess文件的頭部,一般會(huì)顯示為一個(gè)被注釋的一行。通過去除這行的注釋來更改成你所需要使用的環(huán)境設(shè)定。

嵌套變量

為了減少輸入,我們也可以用將變量名包裹在 ${...} 的形式,來重用先前定義過的變量:

  BASE_DIR="/var/webroot/project-root"
  CACHE_DIR="${BASE_DIR}/cache"
  TMP_DIR="${BASE_DIR}/tmp"

命名空間中的變量

有時(shí)候,我們會(huì)遇到多個(gè)變量具有相同名字的情況。當(dāng)這種情況發(fā)生時(shí),系統(tǒng)將沒有辦法獲知這個(gè)變量所對(duì)應(yīng)的確切的值。 我們可以通過將這些變量放入”命名空間“中,來放置這一情況的出現(xiàn)。

在配置文件中,點(diǎn)號(hào)(.)通常被用來表示一個(gè)變量是命名空間變量。這種變量通常是由一個(gè)獨(dú)立前綴,后接一個(gè)點(diǎn)號(hào)(.)然后才是變量名稱本身所組成的:

  // 非命名空間變量
  name = "George"
  db=my_db


  // 命名空間變量
  address.city = "Berlin"
  address.country = "Germany"
  frontend.db = sales
  backend.db = admin
  BackEnd.db = admin

將環(huán)境變量并入配置中

當(dāng)實(shí)例化一個(gè)配置文件時(shí),所有的命名空間中的環(huán)境變量都將會(huì)被并入到這個(gè)實(shí)例對(duì)象的屬性中。

如果一個(gè)命名空間變量的前綴(以大小寫敏感的方式)可以正確匹配到配置類的名稱,那么這個(gè)變量名的剩余部分(點(diǎn)號(hào)后面的部分)將會(huì)被當(dāng)做一個(gè)配置項(xiàng)屬性。 如果這個(gè)變量能夠匹配到一個(gè)已經(jīng)存在的配置項(xiàng)屬性,那么相對(duì)應(yīng)的配置項(xiàng)屬性值將會(huì)被覆蓋。當(dāng)沒有匹配到時(shí),配置項(xiàng)屬性值將不會(huì)被更改。

對(duì)于”短前綴“而言也是如此,當(dāng)環(huán)境變量的前綴匹配到一個(gè)被轉(zhuǎn)換到小寫的配置類名時(shí),首字母也將被替換成相對(duì)應(yīng)的大小寫情況。

以數(shù)組的方式調(diào)用環(huán)境變量

從更長遠(yuǎn)的角度來看,一個(gè)命名空間環(huán)境變量也可以以數(shù)組的方式被調(diào)用。 如果一個(gè)命名空間環(huán)境變量的前綴與某個(gè)配置類所匹配,那么這個(gè)變量的剩余部分,若同樣包含點(diǎn)號(hào),則將會(huì)被當(dāng)做一個(gè)數(shù)組的引用來調(diào)用:

  // 常規(guī)的命名空間變量
  SimpleConfig.name = George


  // 數(shù)組化的命名空間變量
  SimpleConfig.address.city = "Berlin"
  SimpleConfig.address.country = "Germany"

如果這個(gè)變量是對(duì)SimpleConfig配置類的成員的引用,上述例子將會(huì)如下圖所示:

  $address['city'] = "Berlin";
  $address['country'] = "Germany";

$address 屬性的其他部分將不會(huì)被改動(dòng)。

我們同樣可以將數(shù)組屬性名作為前綴來使用,當(dāng)配置文件如下所示時(shí):

  // array namespaced variables
  SimpleConfig.address.city = "Berlin"
  address.country = "Germany"

結(jié)果與原來的相同

注冊器

一個(gè)配置文件可以指定任意數(shù)量的”注冊器“;這里所指的注冊器為其他類可能提供的額外的配置屬性。 這一行為通常通過在配置文件中增加一個(gè) registrars 屬性來實(shí)現(xiàn),這一屬性存有一個(gè)可選的注冊器數(shù)組。:

  protected $registrars = [
      SupportingPackageRegistrar::class
  ];

為了實(shí)現(xiàn)”注冊器“的功能,這些類中必須聲明一個(gè)與配置類同名的靜態(tài)方法,而這一方法應(yīng)當(dāng)返回一個(gè)包含有屬性配置項(xiàng)的關(guān)聯(lián)數(shù)組。

當(dāng)我們實(shí)例化了一個(gè)配置類的對(duì)象后,系統(tǒng)將自動(dòng)循環(huán)搜索在 $registrars 中指定的類。 對(duì)于這些類而言,當(dāng)其中包含有與該配置類同名的方法時(shí),框架將調(diào)用這一方法,并將其返回的所有屬性,如同上節(jié)所述的命名空間變量一樣,并入到配置項(xiàng)中。

配置類舉例如下:

  <?php namespace App\Config;
  use CodeIgniter\Config\BaseConfig;
  class MySalesConfig extends BaseConfig
  {
      public $target        = 100;
      public $campaign      = "Winter Wonderland";
      protected $registrars = [
          '\App\Models\RegionalSales';
      ];
  }

… 所關(guān)聯(lián)的地區(qū)銷售模型將如下所示:

  <?php namespace App\Models;
  class RegionalSales
  {
      public static function MySalesConfig()
      {
          return ['target' => 45, 'actual' => 72];
      }
  }

如上所示,當(dāng) MySalesConfig 被實(shí)例化后,它將以兩個(gè)屬性的被聲明而結(jié)束,然而 $target 屬性將會(huì)被 RegionalSalesModel 的注冊器所覆蓋,故而最終的配置屬性為:

  $target = 45;
  $campaign = "Winter Wonderland";
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)