配置
每个框架都使用配置文件来定义许多参数和初始设置。CodeIgniter 配置文件定义简单的类,其中所需的设置是公共属性。
与许多其他框架不同,CodeIgniter 可配置项不包含在单个文件中。相反,每个需要可配置项的类都将有一个与使用它的类同名的配置文件。您将在 app/Config 文件夹中找到应用程序配置文件。
使用配置文件
获取配置对象
您可以通过几种不同的方式访问类的配置文件。
new 关键字
通过使用 new
关键字创建实例
<?php
// Creating new configuration object by hand
$config = new \Config\Pager();
config()
通过使用 config()
函数
<?php
// Get shared instance with config function
$config = config('Pager');
// Access config class with namespace
$config = config('Config\\Pager');
$config = config(\Config\Pager::class);
// Creating a new object with config function
$config = config('Pager', false);
如果没有提供命名空间,它将首先在 app/Config 文件夹中查找文件,如果未找到,则在所有定义的命名空间中的 Config 文件夹中查找。
所有与 CodeIgniter 一起提供的配置文件都使用 Config
命名空间。在您的应用程序中使用此命名空间将提供最佳性能,因为它确切地知道在哪里查找文件。
注意
在 v4.4.0 之前,config()
在存在具有相同短名称的类时在 app/Config/ 中查找文件,即使您指定了完全限定的类名,例如 config(\Acme\Blog\Config\Blog::class)
。此行为已在 v4.4.0 中修复,并返回指定的实例。
获取配置属性
所有配置对象属性都是公开的,因此您可以像访问任何其他属性一样访问设置。
<?php
$config = config('Pager');
// Access settings as object properties
$pageSize = $config->perPage;
创建配置文件
当您需要一个新的配置时,首先您需要在您想要的位置创建一个新文件。默认文件位置(大多数情况下推荐)是 **app/Config**。
您可以通过使用不同的命名空间将配置文件放在任何 **Config** 文件夹中。
该类应该使用适当的命名空间,并且应该扩展 CodeIgniter\Config\BaseConfig
以确保它可以接收特定于环境的设置。
定义类并用表示您的设置的公共属性填充它。
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class CustomClass extends BaseConfig
{
public $siteName = 'My Great Site';
public $siteEmail = '[email protected]';
// ...
}
环境变量
如今,应用程序设置的最佳实践之一是使用环境变量。这样做的一大原因是环境变量易于在部署之间更改,而无需更改任何代码。配置在部署之间可能会发生很大变化,但代码不会。例如,多个环境(例如开发人员的本地机器和生产服务器)通常需要针对每个特定设置的不同配置值。
环境变量还应用于任何私密信息,例如密码、API 密钥或其他敏感数据。
Dotenv 文件
CodeIgniter 通过使用“dotenv”文件使设置环境变量变得简单且轻松。该术语来自文件名,该文件名以点开头,然后是“env”。
创建 Dotenv 文件
CodeIgniter 期望 **.env** 文件位于项目的根目录,与 **app** 目录并列。CodeIgniter 分发了一个模板文件,该文件位于项目的根目录,名为 **env**(注意,开头没有点 (.
)?)。
它包含项目可能使用的许多变量,这些变量已被分配了空值、虚拟值或默认值。您可以通过将模板重命名为 **.env** 或通过制作名为 **.env** 的副本,将此文件用作应用程序的起点。
警告
确保 **.env** 文件未被您的版本控制系统跟踪。对于 *git*,这意味着将其添加到 **.gitignore** 中。如果未这样做,可能会导致敏感凭据暴露给公众。
设置变量
设置存储在 **.env** 文件中,以简单的键值对形式存储,键值对之间用等号分隔。
S3_BUCKET = dotenv
SECRET_KEY = super_secret_key
CI_ENVIRONMENT = development
当您的应用程序运行时,**.env** 文件将自动加载,并将变量放入环境中。如果环境中已存在该变量,则不会被覆盖。
获取变量
可以使用以下任何一种方法访问加载的环境变量:getenv()
、$_SERVER
或 $_ENV
。
<?php
$s3_bucket = getenv('S3_BUCKET');
$s3_bucket = $_ENV['S3_BUCKET'];
$s3_bucket = $_SERVER['S3_BUCKET'];
警告
请注意,来自 **.env** 文件的设置将被添加到 $_SERVER
和 $_ENV
中。作为副作用,这意味着如果您的 CodeIgniter 应用程序(例如)正在生成 var_dump($_ENV)
或 phpinfo()
(用于调试或其他有效原因),或者在 development
环境中显示详细的错误报告,则 **您的安全凭据将公开暴露**。
嵌套变量
为了节省输入,您可以通过将变量名用 ${...}
包裹来重复使用您已经在文件中指定的变量。
BASE_DIR = "/var/webroot/project-root"
CACHE_DIR = "${BASE_DIR}/cache"
TMP_DIR = "${BASE_DIR}/tmp"
命名空间变量
有时您会遇到多个同名变量。系统需要一种方法来识别正确的设置。这个问题可以通过对变量进行“命名空间”来解决。
命名空间变量使用点符号来限定变量名,以便在合并到环境中时保持唯一性。这可以通过在变量名前添加一个区分前缀,后跟一个点 (.),然后是变量名本身来实现。
// not namespaced variables
name = "George"
db = my_db
// namespaced variables
address.city = "Berlin"
address.country = "Germany"
frontend.db = sales
backend.db = admin
BackEnd.db = admin
命名空间分隔符
某些环境(例如 Docker、CloudFormation)不允许变量名包含点 (.
)。在这种情况下,从 v4.1.5 版本开始,您也可以使用下划线 (_
) 作为分隔符。
// namespaced variables with underscore
app_forceGlobalSecureRequests = true
app_CSPEnabled = true
配置类和环境变量
当您实例化一个配置类时,任何命名空间的环境变量都会被考虑合并到配置对象的属性中。
重要
您不能通过设置环境变量来添加新的属性,也不能将标量值更改为数组。请参见 环境变量作为数据的替换.
注意
此功能在 CodeIgniter\Config\BaseConfig
类中实现。因此,它不适用于 app/Config 文件夹中不扩展该类的几个文件。
如果命名空间变量的前缀与配置类的命名空间完全匹配,则设置的尾部(点之后)将被视为配置属性。如果它与现有的配置属性匹配,则环境变量的值将替换配置文件中的对应值。如果没有匹配,则配置类的属性将保持不变。在这种用法中,前缀必须是类的完整(区分大小写)命名空间。
Config\App.forceGlobalSecureRequests = true
Config\App.CSPEnabled = true
注意
命名空间前缀和属性名称都区分大小写。它们必须与配置类文件定义的完整命名空间和属性名称完全匹配。
同样适用于短前缀,它是一个仅使用配置类名称的小写版本的命名空间。如果短前缀与类名匹配,则来自 .env 的值将替换配置文件的值。
app.forceGlobalSecureRequests = true
app.CSPEnabled = true
从 v4.1.5 开始,您也可以使用下划线编写
app_forceGlobalSecureRequests = true
app_CSPEnabled = true
注意
使用短前缀时,属性名称必须与类定义的名称完全匹配。
环境变量作为数据的替换
务必始终记住,.env 中包含的环境变量只是现有数据的替换。
简而言之,您只能通过在 .env 中设置来更改 Config 类中存在的属性值。
您不能添加 Config 类中未定义的属性,也不能将定义属性的值更改为数组,即使该属性的值是标量。
例如,您不能只是在您的 **.env** 文件中添加 app.myNewConfig = foo
,并期望您的 Config\App
在运行时神奇地拥有该属性和值。
当您在 Config\Database
中拥有属性 $default = ['encrypt' => false]
时,即使您在 **.env** 文件中添加 database.default.encrypt.ssl_verify = true
,您也不能将 encrypt
值更改为数组。如果您想这样做,请参阅 数据库配置。
将环境变量视为数组
命名空间环境变量可以进一步被视为数组。如果前缀与配置类匹配,则如果环境变量名称也包含点,则环境变量名称的其余部分将被视为数组引用。
// regular namespaced variable
Config\SimpleConfig.name = George
// array namespaced variables
Config\SimpleConfig.address.city = "Berlin"
Config\SimpleConfig.address.country = "Germany"
如果这是指 SimpleConfig 配置对象,则上面的示例将被视为
<?php
$address['city'] = 'Berlin';
$address['country'] = 'Germany';
$address
属性的任何其他元素将保持不变。
您也可以使用数组属性名称作为前缀。如果环境文件包含以下内容,则结果将与上面相同。
// array namespaced variables
Config\SimpleConfig.address.city = "Berlin"
address.country = "Germany"
处理不同的环境
通过使用单独的 **.env** 文件,其中包含修改后的值以满足该环境的需求,可以轻松地配置多个环境。
该文件不应包含应用程序使用的每个配置类的所有可能设置。实际上,它应该只包含特定于环境的项目,或者敏感信息,如密码和 API 密钥以及其他不应公开的信息。但是,任何在部署之间发生变化的项目都是可以的。
在每个环境中,将 **.env** 文件放置在项目的根文件夹中。对于大多数设置,这将与 app
目录处于同一级别。
不要使用您的版本控制系统跟踪 **.env** 文件。如果您这样做,并且存储库被公开,您将把敏感信息放在每个人都可以找到的地方。
注册器
“注册器”是任何其他可能提供额外配置属性的类。注册器提供了一种在运行时跨命名空间和文件更改配置的方法。
如果在 模块 中启用了 自动发现,则注册器有效。它在实例化 Config 对象时更改配置属性。
实现注册器有两种方法:**隐式** 和 **显式**。
注意
来自 **.env** 的值始终优先于注册器。
隐式注册器
隐式注册器可以更改任何 Config 类属性。
任何命名空间都可以通过使用 **Config/Registrar.php** 文件来定义隐式注册器。这些文件是类,其方法以您希望扩展的每个配置类的名称命名。
例如,第三方模块或 Composer 包可能希望向 Config\Pager
提供一个额外的模板,而不会覆盖开发人员已经配置的内容。在 **src/Config/Registrar.php** 中,将有一个 Registrar
类,其中包含单个 Pager()
方法(注意大小写敏感性)。
<?php
namespace CodeIgniter\Shield\Config;
class Registrar
{
public static function Pager(): array
{
return [
'templates' => [
'module_pager' => 'MyModule\Views\Pager',
],
];
}
}
注册器方法必须始终返回一个数组,其键对应于目标配置文件的属性。现有值将被合并,并且注册器属性具有覆盖优先级。
显式注册器
显式注册器只能更改它们注册的 Config 类属性。
配置文件还可以显式指定任意数量的注册器。这是通过在配置文件中添加一个 $registrars
属性来完成的,该属性保存候选注册器名称的数组。
<?php
namespace Config;
// ...
class MyConfig extends BaseConfig
{
public static $registrars = [
SupportingPackageRegistrar::class,
];
// ...
}
为了充当“注册器”,如此标识的类必须具有与配置类同名的静态函数,并且它应该返回一个关联数组的属性设置。
当您的配置对象被实例化时,它将循环遍历 $registrars
中指定的类。对于这些类中的每一个,它将调用以配置类命名的函数,并将任何返回的属性合并。
此配置类的示例设置
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class MySalesConfig extends BaseConfig
{
public int $target = 100;
public string $campaign = 'Winter Wonderland';
public static $registrars = [
'\App\Models\RegionalSales',
];
}
…以及相关的区域销售模型可能如下所示
<?php
namespace App\Models;
class RegionalSales
{
public static function MySalesConfig(): array
{
return [
'target' => 45,
];
}
}
在上面的示例中,当 MySalesConfig
被实例化时,它将最终拥有三个声明的属性,但 $target
属性的值将被覆盖,方法是将 RegionalSales
视为“注册器”。最终的配置属性
<?php
$target = 45;
$campaign = 'Winter Wonderland';