新建container
laravel框架public目录下新建container.php,先建立user和log两个类供后续,实例化容器
require __DIR__.'/../vendor/autoload.php';
use Illuminate\Container\Container;
class User
{
public $param;
public $log;
public function __construct($param = Null, Log $log)
{
$this->param = $param;
$this->log = $log;
}
public static function run($runParam)
{
return $runParam;
}
}
class Log
{
}
$container = new Container();
方法名 | 描述 | 调用方法 |
---|
make | 生成一个实例并自动解决依赖关系 | $container->make( $abstract, array $parameters = []) | bind | 绑定方法 | $container->bind(Transistor::class, function( $app) { //… }); | bound | 是否被bind过 | $container->bound( $abstract) | has | 等同bound | $container->has( $abstract) | resolved | 是否被make过 | $container->resolved( $abstract) | alias | 设置别名 | $container->alias( $abstract, $alias) | isAlias | 是否为别名 | $container->isAlias( $name) | build | 最简版的能解决DI注入的IOC容器 | $container->build( $concrete) |
bind 绑定方法
bind bindIf 已resolved解析过的,再次bind会rebound
$container->bind('user', function ($app) {
return new User('bind', new Log);
});
echo $container->user->param;
$container->bindIf('user', function ($app) {
return new User('bindIf', new Log);
});
echo $container->user->param;
singleton单例
singleton单例模式绑定,仅绑定一次,不会重复绑定
$container->singleton('user');
$container->make('user')->param = 'change';
$container->make('user')->log->tag = 'tag';
echo $container->user->param;
echo $container['user']->log->tag;
instance 注册实例
instance 注册实例缓存 make时直接返回注册内容 如果之前bind过会触发rebound
$container->instance('user', new User('param', new log));
echo $container->user->param;.PHP_EOL;
echo $container->make('user', ['param' => 'new param'])->param.PHP_EOL;
$container->when('user')->needs('$param')->give('new param with when');
echo $container->make('user')->param;
extend 绑定扩展
extend 生成实例后会依次执行绑定的extend
$container->extend('user', function($instances, $app) {
$instances->param = 1;
return $instances;
});
$container->extend('user', function($instances, $app) {
$instances->param += 2;
return $instances;
});
echo $container->make('user')->param;
tag 标签
tag 按类别给多个服容器者打标签 tagged逐个make
$container->bind('user1', function($app) {
return new User('user1', new Log);
});
$container->bind('user2', function($app) {
return new User('user2', new Log);
});
$container->tag(['user1', 'user2'], 'userTags');
$userTags = $container->tagged('userTags');
echo 'count:'.count($userTags) . PHP_EOL;
foreach ($userTags as $obj) {
echo $obj->param . PHP_EOL;
}
resolving 钩子
resolving resolve的后置钩子
$container->resolving('user', function ($instance, $app) {
echo 'make user done' . PHP_EOL;
});
$container->make('user');
$container->bind('user', 'user', true);
$container->make('user');
$container->make('user');
$container->resolving(function ($instance, $app) {
echo 'make done' . PHP_EOL;
});
$container->make('user');
refresh 监听
refresh 监听绑定的实例发生更改时执行,等同rebinding ,把匿名函数的方式改成 class->metohd的方式
class handler {
public function deal($instance) {
echo ' change to ' . $instance->param . PHP_EOL;
}
}
$container->bind('user', function ($app) {
return new User('user', new Log);
});
echo $container->make('user')->param;
$oldInstance = $container->refresh('user', new handler, 'deal');
$container->bind('user', function ($app) {
return new User('user2', new Log);
});
rebinding 监听
rebinding 监听绑定的实例发生更改时执行 可以设置多个 一般有三种情况 重新bind 或者加extend 或者设置instance
$container->bind('user', function ($app) {
return new User('user', new Log);
});
$oldInstance = $container->rebinding('user', function ($app, $instance) {
echo ' to ' . $instance->param . PHP_EOL;
});
echo 'change ' . $oldInstance->param;
$container->bind('user', function ($app) {
return new User('user2', new Log);
});
call 执行class->method
call 执行class->method 第二个参数为带入的参数
echo $container->call('User@run', ['runParam' => 'user1']).PHP_EOL;
echo $container->call(['User', 'run'], ['runParam' => 'user2']).PHP_EOL;
echo $container->call('User', ['runParam' => 'user3'], 'run').PHP_EOL;
$container->call(function (User $user, $otherParam) {
echo $user->run($otherParam).PHP_EOL;
}, ['otherParam' => 'user4']);
bindMethod 绑定方法
bindMethod:绑定方法 不能重复绑定
$container->bindMethod('testMethod', function ($instance, $app) {
$app->bind('callBackUser', function($app) use ($instance){
return $instance;
});
});
echo $container->hasMethodBinding('testMethod');
$container->callMethodBinding('testMethod', new User('param_value', new log));
echo 'class User->param:'.$container->make('callBackUser')->param.PHP_EOL;
echo 'class User->run:'.$container['callBackUser']->run('run_value').PHP_EOL;
addContextualBinding
addContextualBinding绑定上下文
$container->addContextualBinding('User', '$param', 'param_value');
$container->addContextualBinding('User', 'Log', function($app) {
$log = new Log();
$log->tag = 'by addContextualBinding';
return $log;
});
echo '$param:'.$container['User']->param.PHP_EOL;
echo 'class User->run:'.$container['User']->run('run_value').PHP_EOL;
echo 'class Log->tag:'.$container['User']->log->tag.PHP_EOL;
wrap 打包
wrap 打包一个方法
$closuer = $container->wrap(function(User $user, $param) {
echo $param;
}, ['param' => 'wrap']);
call_user_func($closuer);
factory打包
factory打包 一个make方法
$closure = $container->factory('user');
$userInstance = call_user_func($closure);
$userInstance->param = 'user';
echo $userInstance->param;
forget清除系列
$container->forgetExtenders('user');
$container->forgetInstance('user');
$container->forgetInstances();
$container->flush();
ArrayAccess接口
isset($container['user']);
$container['user'];
$container['user']->param = 'new param';
unset($container['user']);
|