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, поэтому я могу быть вне базы с ними)

  1. на make метод используется для создания экземпляров объектов. Когда вы говорите App::make('Data') вы говорите Laravel создать экземпляр объекта из класса Data.

  2. есть оговорка к номеру 1. Если вы позвоните make и уже связали строку Data Для что-то в контейнер, что Laravel будет вернуть. Это может означать, что Laravel создает экземпляр нового объекта службы или Laravel возвращает одноэлемент службы

  3. возвращает ли Laravel синглтон или экземпляр для службы зависит от как служба была связаны

  4. на make метод ничего не связывает

  5. вы связываете службы с объектом приложения bind метод, определенный в классе контейнера со следующим прототипом метода public function bind($abstract, $concrete = null, $shared = false)

  6. третий ? Если это правда, ваша служба вернет синглтон. Если это false, ваша служба вернет экземпляры.

  7. в метод - это метод брошюровки

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 класса.