Secure Trading的逆控制(IoC)包。

3.0.0 2021-04-20 13:26 UTC

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

AB实际上是相同的;同样,CD也是相同的。如果使用AB,则构造函数将自动创建一个\Securetrading\Ioc\Ioc实例并将其分配给Helper;如果使用CD,则将给定的\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()。这些函数执行以下操作

  1. 解析所有加载的辅助文件。
  2. 根据辅助文件定义的“包”构建一个数组。
  3. 通过读取辅助文件中的别名定义,并通过调用\Securetrading\Ioc\Ioc::get()将它们设置为IoC实例,加载由loadPackage()loadPackages()调用请求的包。
  4. 加载任何依赖的包,对它们重复上述步骤。这允许例如包A自动加载包BC的定义,而无需在loadPackage()调用中显式请求加载包BC。这对于例如在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.