Рубрики
Uncategorized

Понимание реализации PHP-контейнера

Автор оригинала: David Wong.

Смотрите исходный код Laravel для контейнера

Основные функции контейнеров для инъекций зависимостей:

  • Создание экземпляра объекта управления контейнером в процессе настройки
  • Сами объекты не знают, что они управляются Контейнером, и они не знают контейнера.

Вот почему контейнер может управлять любым объектом PHP. Объекты, использующие DI для управления зависимостями, хороши, но не являются необходимыми.

i

php
function info($msg){
    echo $msg;
}

class LogToFile {
    public function execute($message) {
        Info ('log the message to a goat:'. $message);
    }
}

class UseLogger {
    protected $logger;

    public function __construct(LogToFile $logger) {
        $this->logger = $logger;
    }

    public function show() {
        $user = little grey;
        $this->logger->execute($user);
    }
}

$useLogger = new UseLogger(new LogToFile());

$useLogger->show();

ii

A

logger = $logger;
    }

    public function show() {
        $user = little grey;
        $this->logger->execute($user);
    }
}
$useLogger = new UseLogger(new LogToFile());
 
$useLogger->show();

B

logger = $logger;
    }

    public function show() {
        $user = little grey;
        $this->logger->execute($user);
    }
}
$useLogger = new UseLogger(new LogToDD());
 
$useLogger->show();

iii

logger = $logger;
    }

    public function show() {
        $user = little grey;
        $this->logger->execute($user);
    }
}

$useLogger = new UseLogger(new LogToFile());
 
$useLogger->show();

echo '
'; $useLogger = new UseLogger(new LogToDD()); $useLogger->show();

Окончательное издание

logger = $logger;
    }

    public function show() {
        $user = little grey;
        $this->logger->execute($user);
 
    }
}

class SimpleContainer {

    // Used to store all bindings key-value
    protected static $container = [];

    public static function bind($name, Callable $resolver) {
        static::$container[$name] = $resolver;
    }

    public static function make($name) {
        if(isset(static::$container[$name])){
            $resolver = static::$container[$name] ;
            return $resolver();
        }
        throw new Exception("Binding does not exist in container");
    }
}

SimpleContainer::bind(Logger::class, function () {
    return new LogToDD();
});

$useLogger3 = new UseLogger(SimpleContainer::make(Logger::class));


$useLogger3->show();

Пример

module = $module;
    }

    public function show(array $target){

        $this->module->activate($target);
    }
}

class PowerA implements SuperModuleInterface
{
    public function activate(array $target)
    {
        echo '
'. __METHOD__;
        print_r(func_get_args());
    }
}

class PowerB implements SuperModuleInterface
{
    public function activate(array $target)
    {
        echo '
'. __METHOD__;
        print_r(func_get_args());
    }
}



class Container
{
    protected $binds;

    protected $instances;

    /**
     * @param $abstract
     * @param $concrete
     * Bind pronouns to containers for subsequent make
     */
    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }

    /**
     * @param $abstract
     * @param array $parameters
     * @return mixed
     * Create Objects
     */
    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        // Put the container object $this in the first element of the parameter array. Use for call_user_func_array
        array_unshift($parameters, $this);
        
        // Here, $this - > binds [$abstract] bound closure function, the execution function parameter is $parameters
        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}


// Create a container (later called a superfactory)
$container = new Container;


// Production scripts for adding super modules to the superfactory
$container->bind('powerA', function($container) {
    return new PowerA;
});

// Ibid.
$container->bind('powerB', function($container) {
    return new PowerB;
});


// Add Superman's production script to the superfactory
$container->bind('superman', function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});



echo "
";

// Start production
$superman_1 = $container->make('superman', ['powerA']);
$superman_1->show(['a' => 1]);

$superman_2 = $container->make('superman', ['powerB']);
$superman_2->show(['b' => 1]);