配置文件?

每一個項目,都需要一種方法來定義不同的全局配置項,而這通常是借助配置文件來實現(xiàn)的。 而配置文件,一般來說,是通過聲明一個將所有的配置項作為公開屬性的類,來實現(xiàn)這一配置過程的。

Unlike many other frameworks, CodeIgniter configurable items aren’t contained in a single file. Instead, each class that needs configurable items will have a configuration file with the same name as the class that uses it. You will find the application configuration files in the /app/Config folder.

訪問配置文件?

You can access configuration files for your classes in several different ways.

  • By using the new keyword to create an instance:

    // Creating new configuration object by hand
    $config = new \Config\Pager();
    
  • By using the config() function:

    // Get shared instance with config function
    $config = config('Pager');
    
    // Access config class with namespace
    $config = config( 'Config\\Pager' );
    
    // Creating a new object with config function
    $config = config('Pager', false);
    

All configuration object properties are public, so you access the settings like any other property:

$config = config('Pager');
// Access settings as object properties
$pageSize = $config->perPage;

若沒有給定namespace(命名空間),框架會在所有可用的、已被定義的命名空間中搜尋所需的文件,就如同 /app/Config/ 一樣。

All of the configuration files that ship with CodeIgniter are namespaced with Config. Using this namespace in your application will provide the best performance since it knows exactly where to find the files.

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

創(chuàng)建配置文件?

When you need a new configuration, first you create a new file at your desired location. The default file location (recommended for most cases) is /app/Config. The class should use the appropriate namespace, and it should extend CodeIgniter\Config\BaseConfig to ensure that it can receive environment-specific settings.

Define the class and fill it with public properties that represent your settings.:

<?php namespace Config;

use CodeIgniter\Config\BaseConfig;

class CustomClass extends BaseConfig
{
    public $siteName  = 'My Great Site';
    public $siteEmail = 'webmaster@example.com';

}

環(huán)境變量?

One of today’s best practices for application setup is to use Environment Variables. One reason for this is that Environment Variables are easy to change between deploys without changing any code. Configuration can change a lot across deploys, but code does not. For instance, multiple environments, such as the developer’s local machine and the production server, usually need different configuration values for each particular setup.

Environment Variables should also be used for anything private such as passwords, API keys, or other sensitive data.

Environment Variables and CodeIgniter?

CodeIgniter makes it simple and painless to set Environment Variables by using a “dotenv” file. The term comes from the file name, which starts with a dot before the text “env”.

CodeIgniter expects .env to be at the root of your project alongside the system and app directories. There is a template file distributed with CodeIgniter that’s located at the project root named env (Notice there’s no dot (.) at the start?). It has a large collection of variables your project might use that have been assigned empty, dummy, or default values. You can use this file as a starting place for your application by either renaming the template to .env, or by making a copy of it named .env.

重要

Make sure the .env file is NOT tracked by your version control system. For git that means adding it to .gitignore. Failure to do so could result in sensitive credentials being exposed to the public.

Settings are stored in .env files as a simple a collection of name/value pairs separated by an equal sign.

S3_BUCKET = dotenv
SECRET_KEY = super_secret_key
CI_ENVIRONMENT = development

When your application runs, .env will be loaded automatically, and the variables put into the environment. If a variable already exists in the environment, it will NOT be overwritten. The loaded Environment variables are accessed using any of the following: getenv(), $_SERVER, or $_ENV.

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

嵌套變量?

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

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

命名空間中的變量?

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

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

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

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

Configuration Classes and Environment Variables?

When you instantiate a configuration class, any namespaced environment variables are considered for merging into the configuration object’s properties.

If the prefix of a namespaced variable exactly matches the namespace of the configuration class, then the trailing part of the setting (after the dot) is treated as a configuration property. If it matches an existing configuration property, the environment variable’s value will replace the corresponding value from the configuration file. If there is no match, the configuration class properties are left unchanged. In this usage, the prefix must be the full (case-sensitive) namespace of the class.

Config\App.CSRFProtection  = true
Config\App.CSRFCookieName = csrf_cookie
Config\App.CSPEnabled = true

注解

Both the namespace prefix and the property name are case-sensitive. They must exactly match the full namespace and property names as defined in the configuration class file.

The same holds for a short prefix, which is a namespace using only the lowercase version of the configuration class name. If the short prefix matches the class name, the value from .env replaces the configuration file value.

app.CSRFProtection  = true
app.CSRFCookieName = csrf_cookie
app.CSPEnabled = true

注解

When using the short prefix the property names must still exactly match the class defined name.

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

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

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

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

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

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

$address 屬性的其他部分將不會被改動。

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

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

Handling Different Environments?

Configuring multiple environments is easily accomplished by using a separate .env file with values modified to meet that environment’s needs.

The file should not contain every possible setting for every configuration class used by the application. In truth, it should include only those items that are specific to the environment or are sensitive details like passwords and API keys and other information that should not be exposed. But anything that changes between deployments is fair-game.

In each environment, place the .env file in the project’s root folder. For most setups, this will be the same level as the system and app directories.

Do not track .env files with your version control system. If you do, and the repository is made public, you will have put sensitive information where everybody can find it.

注冊器?

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

protected $registrars = [
    SupportingPackageRegistrar::class
];

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

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

配置類舉例如下:

<?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 被實例化后,它將以兩個屬性的被聲明而結(jié)束,然而 $target 屬性將會被 RegionalSalesModel 的注冊器所覆蓋,故而最終的配置屬性為:

$target = 45;
$campaign = "Winter Wonderland";