我将给出一个基本的例子,假设我有3个类-- Config、Database和User。User需要Database,Database需要Config,但User也可能需要Config。所有的类只需要一个实例,因为我只需要加载配置文件一次,只需连接数据库一次,并检查用户是否登录并只获取一次数据。现在,从每个类中判断需要哪些类并让它们自动加载的最佳方法是什么?或者这是一种糟糕的训练,我只是在偷懒?我试着让所有类都是单个的,并在每个类中这样访问它们:
User.php
$this->db = Module::get('Database');但是,当我第一次创建一个类的新实例时,我不得不创建一个自定义的__construct()方法并运行该方法,这让我感到非常失望。我做了一些研究,并读到singletons并不是一个很好的实践,dependency-injection将是一个更好的解决方案,但是我不知道如何使用dependency-injection来实现这一点。所以我想知道,这到底是个好主意,还是我应该重新思考一下,我希望一切都能正常运转?
发布于 2016-01-14 15:40:02
用户需要数据库,数据库需要Config,但用户也可能需要Config
听起来你需要依赖注入。有一些现有的包可以做到这一点,但是如果您自己制作它,您可以创建一个名为DIContainer的类,它的唯一目的是设置和获取对象实例,然后将这个类传递给可能需要它中的内容的其他类。
class DIContainer {
protected $_objects = array();
public function __set( $name='', $instance=null )
{
if( !empty( $name ) && is_object( $instance ) )
{
$this->_objects[ $name ] = $instance;
}
}
public function __get( $name='' )
{
if( !empty( $name ) && array_key_exists( $name, $this->_objects ) )
{
return $this->_objects[ $name ];
}
throw new Exception( 'Object not found ('.$name.').' );
}
}然后实例化并设置您的公共类并将它们添加到DIContainer中:
// setup config
$config = new Config();
$config->loadFile( './conf.php' );
// setup db
$database = new Database( $config );
$database->connect();
// setup session
$session = new Session( $config );
$session->start();
// save dependencies
$container = new DIContainer;
$container->config = $config;
$container->database = $database;
$container->session = $session;
// later when you start a new User class
$user = new User( $container ); 现在,用户类可以得到它需要的东西,只需设置构造函数方法来处理DIContainer:
class User {
protected $container = null;
public function __construct( DIContainer $container )
{
$this->container = $container;
}
public function getRows()
{
$rows = $this->container->database->getRows( '...' );
}
}发布于 2016-01-12 12:06:03
您正在寻找php中的自动加载。这一主题已经讨论过,并有一些很好的解释这里。
简单地说,在文件开始时(声明名称空间之后),可以告诉php类依赖于什么。
namespace Entity;
use ORM\Database;
use Config;
//...
$d = new Database();
Config::set('a', 'b');在使用外部库和管理代码中的自动加载时,您还可能希望使用作曲家来获取DI,而不需要重新创建方向盘。
下面是作曲家文档中关于自动加载的内容:
对于指定autoload信息的库,Composer将生成一个供应商/autooload.php文件。您可以简单地包括这个文件,您将获得免费自动加载。 需要__DIR__。‘/卖主/autooload.php’; 这使得使用第三方代码变得非常容易。例如:如果您的项目依赖于Monolog,您可以从它开始使用类,它们将自动加载。 $log =新Monolog\Logger('name');$log->pushHandler(新Monolog\Handler\StreamHandler('app.log',Monolog\Logger::警告);$log->addWarning('Foo'); 您甚至可以通过向composer.json添加一个autoload字段,将自己的代码添加到自动加载程序中。 { "autoload":{ "psr-4":{"Acme\":"src/"} }
https://stackoverflow.com/questions/34743028
复制相似问题