securetrading / ioc
Secure Trading的逆控制(IoC)包。
Requires
- php: ^8.0
- securetrading/exception: ^1.0
Requires (Dev)
- mikey179/vfsstream: ^1.6
- securetrading/unittest: ^3.0
This package is not auto-updated.
Last update: 2024-09-18 05:54:20 UTC
README
其他Secure Trading包使用的辅助包。
提供了一个逆控制类\Securetrading\Ioc\Ioc
。此类的实例可以将'别名'映射到类名或工厂方法;然后可以使用这些别名来实例化对象。
它还提供了一个辅助类\Securetrading\Ioc\Helper
,应用程序可以使用它轻松地将别名映射注册到Securetrading\Ioc\Ioc
实例,而无需应用程序代码显式调用Securetrading\Ioc\Ioc::get()
。
发布历史
PHP版本兼容性
\Securetrading\Ioc\Ioc - 使用方法
可以通过以下方式构造实例:
$ioc = new \Securetrading\Ioc\Ioc();
或者这样:
$ioc = \Securetrading\Ioc\Ioc::instance();
使用set()
注册别名
$ioc->set('anAlias', '\stdClass');
使用get()
创建实例
$ioc->set('anAlias', '\stdClass');
$instance = $ioc->get('anAlias');
var_dump(get_class($instance)); // "stdClass"
可以将一个可选数组传递给get()
。此数组中的值将传递给构造实例的构造函数
class A {
public function __construct($a, $b) {
echo "values are " . $a . " and " . $b . PHP_EOL; // Outputs "values are param1 and param2"
}
}
$ioc->set('anAlias', '\A');
$instance = $ioc->get('anAlias', ['param1', 'param2']);
如果传递给'get'的别名尚未通过调用set()
进行注册,并且别名实际上是一个有效的类名,则将返回该类的实例
class A {}
var_dump(get_class( $ioc->get('\A') )); // "A"
$ioc->set('\A', '\stdClass');
var_dump(get_class( $ioc->get('\A') )); // "stdClass"
使用has()
检查是否已添加别名
var_dump( $ioc->has('anAlias') ); // false
$ioc->set('anAlias', '\stdClass');
var_dump( $ioc->has('anAlias') ); // true
set()
接受一个别名和一个字面量类名(如之前所示)或工厂方法。当使用别名调用get()
时,将调用此工厂方法。
$ioc->set('anAlias', function(\Securetrading\Ioc\IocInterface $ioc, $alias, $params) {
// $ioc is the same $ioc instance that 'set' is being called on.
// $alias is the alias passed when the 'get' method was called.
// $params come from the second argument to the 'get' method call.
return new \stdClass();
});
$instance = $ioc->get('anAlias', ['optionalAdditionalParam1', 'optionalAdditionalParam2']);
var_dump(get_class($instance)); // stdClass
create()
方法是对get()
的别名
$ioc->get('anAlias');
$ioc->create('anAlias'); // Same as above.
getSingleton()
方法将别名解析为类实例:对getSingleton()
的别名进行多次调用将始终返回相同的实例。
$ioc->set('anAlias', '\stdClass');
var_dump( $ioc->get('anAlias') === $ioc->get('anAlias') ); // false
var_dump( $ioc->getSingleton('anAlias') === $ioc->getSingleton('anAlias') ); // true
可以使用before()
方法注册在从别名构造实例之前将调用的函数
$ioc->set('anAlias', '\stdClass');
$ioc->set('anotherAlias', '\stdClass');
$ioc->before('anAlias', function($alias, array $params = array()) {
echo "in before callback for alias '" . $alias . "'" . PHP_EOL;
});
$ioc->get('anAlias'); // Will trigger the 'before' function
$ioc->get('anotherAlias'); // Will not trigger the 'before' function.
可以使用通配符*
注册一个在构造每个实例之前都会被触发的before回调,而不考虑别名
$ioc->set('anAlias', '\stdClass');
$ioc->set('anotherAlias', '\stdClass');
$ioc->before('*', function($alias, array $params = array()) {
echo "in before callback for alias '" . $alias . "'" . PHP_EOL;
});
$ioc->get('anAlias'); // Will trigger the 'before' function
$ioc->get('anotherAlias'); // Will trigger the 'before' function.
也可以调用after()
实例方法。这与before()
实例方法的工作方式相同,并也接受通配符*
$ioc->set('anAlias', '\stdClass');
$ioc->set('anotherAlias', '\stdClass');
$ioc->after('*', function(\Securetrading\Ioc\IocInterface $ioc, $constructedInstance, $alias, array $params = array()) {
echo "in after callback for alias '" . $alias . "'" . PHP_EOL;
});
$ioc->get('anAlias'); // Will trigger the 'after' function
$ioc->get('anotherAlias'); // Will trigger the 'after' function.
提供了用于管理配置选项的辅助方法。这些方法可能在例如给set()
作为第二个参数提供的工厂方法或在给before()
和after()
方法提供的回调中很有用
$ioc->setOption('our_option', 'our_value');
var_dump( $ioc->hasOption('our_option') ); // true
var_dump( $ioc->hasOption('our_other_option') ); // false
var_dump( $ioc->getOption('our_option') ); // 'our_value'
$ioc->getOption('our_other_option'); // \Securetrading\Ioc\IocException thrown with code CODE_OPTION_MISSING.
还提供了用于检查数组中参数的存在和从数组(或不存在时的默认值)中检索值的辅助方法。这些方法旨在使在工厂方法中将$params
作为可选第二个参数传递给get()
时的工作更容易
var_dump( $ioc->hasParameter('key', []) ); // false
var_dump( $ioc->hasParameter('key', ['key' => 'value']) ); // true
var_dump( $ioc->getParameter('key', [], 'default_value') ); // 'default_value'
var_dump( $ioc->getParameter('key', ['key' => 'value']) ); // 'value'
$ioc->getParameter('key', []); // throws \Securetrading\Ioc\IocException with code CODE_PARAM_MISSING.
\Securetrading\Ioc\Helper - 使用方法
使用Helper
是可选的。
Helper
可以通过解析特殊的'helper文件'来隐式地重复调用\Securetrading\Ioc\Ioc::set()
,这样应用程序就不必始终显式定义大量的别名映射。
可以以以下任何一种方式构建:
$helper = new \Securetrading\Ioc\Helper(); // A
$helper = \Securetrading\Ioc\Helper::instance(); // B
$ioc = new \Securetrading\Ioc\Ioc();
$helper = new \Securetrading\Ioc\Helper($ioc); // C
$helper = \Securetrading\Ioc\Helper::instance($ioc); //D
A
和B
实际上是相同的;同样,C
和D
也是相同的。如果使用A
或B
,则构造函数将自动创建一个\Securetrading\Ioc\Ioc
实例并将其分配给Helper;如果使用C
或D
,则将给定的\Securetrading\Ioc\IocInterface
实例传递给\Securetrading\Ioc\Helper
构造函数,因此它不会自动创建另一个实例。
辅助器首先需要找到有效的“辅助文件”。辅助文件必须命名为*_ioc.php
,其中*
可以是文件名中有效的任何字符。用户必须通过调用以下方法之一(或多个)来告诉辅助器辅助文件的存放位置:addEtcDirs()
和addVendorDirs()
。
addEtcDirs()
告诉辅助器在参数中给出的目录内查找辅助文件
$helper->addEtcDirs('/path/to/an/etc/dir/');
addEtcDirs()
可以重载,因此也可以传入一个辅助文件数组
$helper->addEtcDirs(['/path/to/an/etc/dir/', '/path/to/another/etc/dir']);
addVendorDirs()
是为与基于Composer的应用程序一起使用而设计的,并且应指向由Composer创建的vendor
目录。然后,辅助器将检查每个供应商名称和包名称中的etc
目录。然后,从这个etc
目录中加载所有有效的辅助文件。
$helper->addVendorDir('/path/to/a/composer/based/application/vendor/'); // E.g. a valid helper file might be '/path/to/a/composer/based/application/vendor/vendorName/applicationName/etc/our_ioc.php'
addVendorDirs()
- 如同addEtcDirs()
- 也可以重载,因此一次可以指定多个供应商目录
$helper->addVendorDir(['/path/to/a/composer/based/application/vendor/', '/path/to/another/composer/based/application/vendor/']);
一旦通过addEtcDirs()
或addVendorDirs()
注册了有效辅助文件的位置(见上文),则可以调用loadPackage()
或loadPackages()
。这些函数执行以下操作
- 解析所有加载的辅助文件。
- 根据辅助文件定义的“包”构建一个数组。
- 通过读取辅助文件中的别名定义,并通过调用
\Securetrading\Ioc\Ioc::get()
将它们设置为IoC实例,加载由loadPackage()
或loadPackages()
调用请求的包。 - 加载任何依赖的包,对它们重复上述步骤。这允许例如包
A
自动加载包B
和C
的定义,而无需在loadPackage()
调用中显式请求加载包B
和C
。这对于例如在IoC级别模仿Composer依赖项非常有用。
辅助文件看起来是这样的
return [
'aPackageNameHere' => [
'definitions' => array(
'anAlias' => '\stdClass',
'anotherAlias' => ['\aClass', 'aMethodInTheClass'], // A factory method.
],
'dependencies' => [
'anotherPackageNameHere', // This means that the 'definitions' from the 'anotherPackageNameHere' will also be loaded and set to the IoC container.
],
],
];
对loadPackage()
的调用看起来是这样的
$helper->loadPackage('packageName');
也可以通过调用loadPackages()
加载多个包
$helper->loadPackages(['packageName', 'anotherPackageName']);
在调用loadPackage()
或loadPackages()
之后,可以返回IoC容器
$ioc = $helper->getIoc();
还提供了一些其他方法(主要用于调试)来检查找到的辅助文件和加载的包
var_dump( $helper->getPackageDefinitionFiles() );
var_dump( $helper->getPackageDefinitions() );
var_dump( $helper->getLoadedPackageNames() );
仅供参考 - Helper
的典型使用可能如下所示
$ioc = \Securetrading\Ioc\Helper::instance()
->addVendorDirs(__DIR__ . '/vendor'/)
->loadPackage('ourPackageName')
->getIoc();
$instance = $ioc->get('alias'); // Using the IoC container. Note we did not need to explicitly register 'alias' with the container.