Php 如何全局访问依赖项注入容器

Php 如何全局访问依赖项注入容器,php,Php,我正在用PHP构建自己的小型MVC框架,只是为了学习和更好地理解 我用路由器创建了一个小框架 在我的index.php中,我为我的应用程序创建了一个容器 index.php use \Oak\Route\Route as Route; use \Oak\Route\Routes as Routes; use \Oak\App\App as App; $routes = new Routes(); $routes->addRoute(new Route('home', 'index',

我正在用PHP构建自己的小型MVC框架,只是为了学习和更好地理解

我用路由器创建了一个小框架

在我的index.php中,我为我的应用程序创建了一个容器

index.php

use \Oak\Route\Route as Route;
use \Oak\Route\Routes as Routes;
use \Oak\App\App as App;

$routes = new Routes();

$routes->addRoute(new Route('home', 'index', 'index'));
$routes->addRoute(new Route('user/{username}/{id}', 'index', 'about'));
$routes->addRoute(new Route('help', 'help', 'index'));

$container = new Container();
$container->set('app', function() use ($routes) {
    return new App($routes, new \Oak\Header\Request());
});

$app = $container->get('app');
$app->run();

Container.php和ContainerInterface.php

interface ContainerInterface {

public function set($name, $service);
public function get($name, array $params = array());
public function has($name);
public function remove($name);
public function clear();
}

class Container implements ContainerInterface {

    protected $services = array();

    public function set($name, $service) {
        if(!is_object($service)) {
            throw new InvalidArgumentException("Only objects can be registred");
        }

        if(!in_array($service, $this->services, true)) {
            $this->services[$name] = $service;
        }
        return $this;
    }

    public function get($name, array $params = array()) {
        if(!isset($this->services[$name])) {
            throw new RuntimeException($name ." has not been registred in the container");
        }
        $service = $this->services[$name];

        return !$service instanceof Closure ? $service : call_user_func_array($service, $params);
    }

    public function has($name):bool {
        return isset($this->services[$name]);
    }

    public function remove($name) {
        if(isset($this->services[$name])) {
            unset($this->services[$name]);
        }
        return $this;
    }

    public function clear() {
        $this->services = array();
    }

    public  function getServices():array {
        return $this->services;
    }
}
我现在的问题是如何从我的控制器、我的应用程序文件等启用对容器的访问。一个解决方案是在容器中使用单例或静态方法

我已经读了很多关于这个主题的博客和文章,但是我觉得所有的例子都只与索引文件中的容器通信

我也开始尝试继承,该应用程序扩展容器,然后将其传递给控制器


我的问题是,如果这样做的话,如何从应用程序中的任何地方访问容器?

检查Singleton设计模式。。你需要这样的东西:

class Container {
    private static $instance;
    //prevent from creating a container class by itself
    private function __construct() {};    
    /* .... */
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new Container();
        }
    }
}
然后在代码中随处可见,而不是使用
$container=newcontainer()使用
$container=container::getInstance()

无论如何,我强烈建议您签出一个Pimple(),这是非常好的代码,具有延迟加载。写一些像丘疹这样好的、功能丰富的东西会花费你很多时间