Laravel разница "между app - >bind" и "app - >singleton"?
я пытался выяснить, в чем разница между app->bind
и app->singleton
при настройке поставщика услуг в Laravel. У меня сложилось впечатление, что если я зарегистрирую singleton
он будет возвращать один и тот же экземпляр объекта каждый раз, когда он вызывался vs bind
который будет новым экземпляром.
здесь просто пример:
фасад:
use IlluminateSupportFacadesFacade;
class DataFacade extends Facade
{
protected static function getFacadeAccessor() {
return 'Data';
}
}
ServiceProvider:
use IlluminateSupportServiceProvider;
class DataServiceProvider extends ServiceProvider
{
public function register() {
$this->app->singleton('Data', function() {
return new Data;
});
}
}
класс:
class Data
{
public $data = [];
public function get($key)
{
return isset($this->data[$key]) ? $this->data[$key] : null;
}
public function set($key, $val)
{
$this->data[$key] = $val;
}
}
если мы сделаем что-то вроде:
$instance = App::make('Data');
$instance->set('foo', 'foo');
$instance2 = App::make('Data');
echo $instance->get('foo');
echo $instance2->get('foo');
и запустите, что мы увидим соответствующее поведение между bind
и singleton
С foo
распечатывается один раз, а затем дважды соответственно. Однако, если мы запустим его через фасад так:
Data::set('test', 'test');
Data::set('cheese', 'cheese');
когда это синглтон, я ожидал бы как test
и cheese
будет доступно и когда это bind
Я не уверен, что я ожидал бы быть доступным через фасад, но похоже, что нет никакой разницы.
это фасад, рассматривающий все как singleton
?
1 ответов
ваш вопрос немного запутанный и не имеет всей информации для кого-то, чтобы ответить, но это запутанная тема, поэтому не чувствуйте себя плохо. Вот краткое изложение, которое может помочь вам лучше понять и задать вопрос, который вы хотели задать (кроме того, я новичок в Laravel, поэтому я могу быть вне базы с ними)
на
make
метод используется для создания экземпляров объектов. Когда вы говоритеApp::make('Data')
вы говорите Laravel создать экземпляр объекта из классаData
.есть оговорка к номеру 1. Если вы позвоните
make
и уже связали строкуData
Для что-то в контейнер, что Laravel будет вернуть. Это может означать, что Laravel создает экземпляр нового объекта службы или Laravel возвращает одноэлемент службывозвращает ли Laravel синглтон или экземпляр для службы зависит от как служба была связаны
на
make
метод ничего не связываетвы связываете службы с объектом приложения
bind
метод, определенный в классе контейнера со следующим прототипом методаpublic function bind($abstract, $concrete = null, $shared = false)
третий ? Если это правда, ваша служба вернет синглтон. Если это false, ваша служба вернет экземпляры.
в метод - это метод брошюровки
Re: #7, вот определение singleton
#File: vendor/laravel/framework/src/Illuminate/Container/Container.php
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
в приведенных выше примерах вы связываете службу Data
в контейнер. Использование ведущего имени службы case вызовет проблемы - data
было бы лучшим выбором. Если register
метод почему-то не вызывается, make
по-прежнему будет создавать экземпляр объекта с вашим глобальным классом Data
относительно вашего фасада -- фасад-это дополнительный слой экземпляра/синглтон-Несс. Вот метод, в котором класс facade использует строку из getFacadeAccessor
для возврата объекта из статического вызова
#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) return $name;
if (isset(static::$resolvedInstance[$name]))
{
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
Итак, фасад использует $app[$name];
для того чтобы схватить обслуживание от контейнера. Это ArrayAccess
, поэтому, если мы посмотрим на определение offsetGet
public function offsetGet($key)
{
return $this->make($key);
}
мы видим ArrayAccess
палантины вызов make
. Это означает, что если у вас нет связанного сервиса, facade access создаст экземпляр объекта. Если у вас есть служба, связанная как одноэлементная / общая служба, доступ к фасаду вернет этот одноэлемент. Если служба привязана как не одноэлементная / общая служба, facade access создаст экземпляр нового объекта.
, сам фасад будет хранить любой объект, который он создает внутри static::$resolvedInstance
, и будущие вызовы фасада вернут этот же экземпляр. Это означает, что Facade access вводит второй синглтон реализация. Услуги связаны как синглтон будет храниться на объект приложения, сервис доступен через фасад будет сохранен как синглтон на Facade
класса.