IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 玩转laravel中Container容器类常用方法 -> 正文阅读

[PHP知识库]玩转laravel中Container容器类常用方法

新建container

laravel框架public目录下新建container.php,先建立user和log两个类供后续,实例化容器

/**
 * @author biny
 * @date 2021-08-11 8:45
 */
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;  # 输出bind

//判断是否绑定,上面已绑定过,这次绑定操作被忽略,不会执行
$container->bindIf('user', function ($app) {
    return new User('bindIf', new Log);
});
echo $container->user->param;  # 输出bind,而不是bindIf

singleton单例

singleton单例模式绑定,仅绑定一次,不会重复绑定

$container->singleton('user');  # 绑定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;  # param

//有参数会重新生成实例
echo $container->make('user', ['param' => 'new param'])->param.PHP_EOL;  # new param

//上下文绑定无效 instance是单例缓存
$container->when('user')->needs('$param')->give('new param with when');
echo $container->make('user')->param;  # 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;//输出3

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;
});
//这里会打印两次make done  一次是构建user  一次是构建log(user的依赖)
$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 为以当前绑定方式生成的实例
$oldInstance = $container->rebinding('user', function ($app, $instance) {
    echo ' to ' . $instance->param . PHP_EOL;
});

echo 'change ' . $oldInstance->param;

//重新绑定  触发rebind
$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;

//匿名函数方式  test会自动make
$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;
    });
});
//hasMethodBinding 判断是否绑定了方法
echo $container->hasMethodBinding('testMethod');
//callMethodBinding 执行之前绑定的方法(bind callBackUser)
$container->callMethodBinding('testMethod', new User('param_value', new log));

echo 'class User->param:'.$container->make('callBackUser')->param.PHP_EOL;
//make的简写,使用offsetGet方法
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');  # forgetExtenders 清除扩展extend
$container->forgetInstance('user');  # forgetInstance 清除单例
$container->forgetInstances();  # forgetInstances 清除所有单例
$container->flush();  # 清除$this->aliases = []; $this->resolved = []; $this->bindings = []; $this->instances = []; $this->abstractAliases = [];

ArrayAccess接口

isset($container['user']);  #调用 offsetExists($key) 等同 bound
$container['user'];  # 调用 offsetGet($key) 等同 make
$container['user']->param = 'new param';  # 调用 offsetSet($key, $value) 等同 bind仅限传入闭包方式,非闭包打包成闭包传入bind($key, $value)
unset($container['user']);  # 调用offsetUnset($key) 等同 unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]);
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-08-13 11:42:08  更:2021-08-13 11:45:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 5:28:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码