Luu*_*gen 62 php oop facade ioc-container laravel-4
我对laravel在IOC容器和外墙方面提供的所有好东西感到有些困惑.由于我不是一位经验丰富的程序员,因此学习起来势不可挡.
我想知道,这两个例子有什么区别:
'Foo'的门面并通过容器注册 App::bind()
'Foo'的门面并通过容器注册 App::singleton()
在我的最佳理解Foo::method()中将被重写,$app->make['foo']->method()因为在第一个示例Foo中将创建类的多个实例,并且在第二个示例中,因为它通过a绑定App::singleton(),所以Foo每次调用该对象上的Method时都将返回相同的实例.
如果这个问题的答案显而易见,我很抱歉,但我找不到任何关于这个问题的确认,也没有明确解释.
小智 69
就是这样.
一个非常简单的证据是测试bevahior.由于Laravel应用程序只是扩展Illuminate\Container\Container,我们将只使用容器(在我的情况下,我甚至只将容器添加为我的composer.json的依赖项)进行测试.
require __DIR__ . '/vendor/autoload.php';
class FirstClass
{
public $value;
}
class SecondClass
{
public $value;
}
// Test bind()
$container = new Illuminate\Container\Container();
$container->bind('FirstClass');
$instance = $container->make('FirstClass');
$instance->value = 'test';
$instance2 = $container->make('FirstClass');
$instance2->value = 'test2';
echo "Bind: $instance->value vs. $instance2->value\n";
// Test singleton()
$container->singleton('SecondClass');
$instance = $container->make('SecondClass');
$instance->value = 'test';
$instance2 = $container->make('SecondClass');
$instance2->value = 'test2'; // <--- also changes $instance->value
echo "Singleton: $instance->value vs. $instance2->value\n";
Run Code Online (Sandbox Code Playgroud)
结果如预期:
Bind: test vs. test2
Singleton: test2 vs. test2
可能是一个肮脏的证据,但实际上它是一个.
所有的魔力都在于Container::make方法.如果绑定注册为shared(表示为singleton),则返回类实例,否则每次都返回一个新实例.
资料来源:https://github.com/laravel/framework/blob/4.2/src/Illuminate/Container/Container.php#L442
顺便说一句,Container::singleton是一样的Container::bind设置为true第三个参数.
Gra*_*ble 14
即使底层绑定不是单身,外墙也可以作为单身人士工作.
假设你有:
$app->bind('foo', 'FooConcrete'); // not a singleton
Run Code Online (Sandbox Code Playgroud)
和:
class Foo extends \Illuminate\Support\Facades\Facade {
protected static function getFacadeAccessor() { return 'foo'; }
}
Run Code Online (Sandbox Code Playgroud)
然后这将FooConcrete像往常一样创建2个实例:
app('foo');
app('foo');
Run Code Online (Sandbox Code Playgroud)
但是这只会创建一个实例FooConcrete并重用它:
Foo::someMethod();
Foo::someMethod();
Run Code Online (Sandbox Code Playgroud)
这是因为resolveFacadeInstance()存储已解析的实例.
但有一个例外.大多数情况下,define getFacadeAccessor()返回一个字符串,如上所示,但它也可以返回一个对象.SchemaFacade 示例:
protected static function getFacadeAccessor() {
return static::$app['db']->connection()->getSchemaBuilder();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,resolveFacadeInstance()不存储实例.
因此,如果getFacadeAccessor()返回一个新实例,每次调用Facade也会创建一个新实例.