Laravel中使用Ioc容器的singleton方法和bind方法创建实例的区别

本文通过实例对比了Ioc容器中Singleton与Bind两种注册方式的不同。Singleton确保每次获取相同实例,适用于需要全局唯一对象的场景;而Bind则每次创建新实例,适合对象需频繁创建的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

它们两个都是返回一个类的实例,不同的是singleton是单例模式,而bind是每次返回一个新的实例,看下面的两个例子。

1.Ioc容器bind方法

<?php
require __DIR__.'/../bootstrap/autoload.php';


class tanteng

{

    public $name="init_str";

}



$container = new Illuminate\Container\Container();

$container->bind('tanteng');

$instance = $container->make('tanteng');

$instance->name = 'tanteng';

$instance2 = $container->make('tanteng');

//$instance2->name = 'tuntun';


echo $instance->name.' '.$instance2->name;

输出的结果:

tanteng init_str

结论:

通过bind方法创建实例不是单例模式,而是创建新的实例。

2.Ioc容器singleton方法

<?php
require __DIR__.'/../bootstrap/autoload.php';


class single

{

    public $value;

}


$container = new Illuminate\Container\Container();


$container->singleton('single');

$instance3 = $container->make('single');

$instance4 = $container->make('single');



$instance3->value = 'aaaa';

$instance4->value = 'bbbb';



echo $instance3->value.' '.$instance4->value;

输出结果:

bbbb bbbb

结论:

使用singleton创建实例使用的是单例模式,每次返回同一个实例。

以上代码可以放在public下,如test.php运行。

再看框架底层代码:

public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}

发现singleton方法其实也是调用bind方法,只是最后一个参数是true,表示单例模式。框架源代码:Illuminate/Container/Container.php

附上bind()方法

public function bind($abstract, $concrete = null, $shared = false)
    {
        $abstract = $this->normalize($abstract);

        $concrete = $this->normalize($concrete);

        // If the given types are actually an array, we will assume an alias is being
        // defined and will grab this "real" abstract class name and register this
        // alias with the container so that it can be used as a shortcut for it.
        if (is_array($abstract)) {
            list($abstract, $alias) = $this->extractAlias($abstract);

            $this->alias($abstract, $alias);
        }

        // If no concrete type was given, we will simply set the concrete type to the
        // abstract type. After that, the concrete type to be registered as shared
        // without being forced to state their classes in both of the parameters.
        $this->dropStaleInstances($abstract);

        if (is_null($concrete)) {
            $concrete = $abstract;
        }

        // If the factory is not a Closure, it means it is just a class name which is
        // bound into this container to the abstract type and we will just wrap it
        // up inside its own Closure to give us more convenience when extending.
        if (! $concrete instanceof Closure) {
            $concrete = $this->getClosure($abstract, $concrete);
        }

        $this->bindings[$abstract] = compact('concrete', 'shared');

        // If the abstract type was already resolved in this container we'll fire the
        // rebound listener so that any objects which have already gotten resolved
        // can have their copy of the object updated via the listener callbacks.
        if ($this->resolved($abstract)) {
            $this->rebound($abstract);
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值