首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >允许类相互访问并自动发生这种情况的最佳方法?

允许类相互访问并自动发生这种情况的最佳方法?
EN

Stack Overflow用户
提问于 2016-01-12 11:55:28
回答 2查看 79关注 0票数 1

我将给出一个基本的例子,假设我有3个类-- ConfigDatabaseUserUser需要DatabaseDatabase需要Config,但User也可能需要Config。所有的类只需要一个实例,因为我只需要加载配置文件一次,只需连接数据库一次,并检查用户是否登录并只获取一次数据。现在,从每个类中判断需要哪些类并让它们自动加载的最佳方法是什么?或者这是一种糟糕的训练,我只是在偷懒?我试着让所有类都是单个的,并在每个类中这样访问它们:

User.php

代码语言:javascript
复制
$this->db = Module::get('Database');

但是,当我第一次创建一个类的新实例时,我不得不创建一个自定义的__construct()方法并运行该方法,这让我感到非常失望。我做了一些研究,并读到singletons并不是一个很好的实践,dependency-injection将是一个更好的解决方案,但是我不知道如何使用dependency-injection来实现这一点。所以我想知道,这到底是个好主意,还是我应该重新思考一下,我希望一切都能正常运转?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-14 15:40:02

用户需要数据库,数据库需要Config,但用户也可能需要Config

听起来你需要依赖注入。有一些现有的包可以做到这一点,但是如果您自己制作它,您可以创建一个名为DIContainer的类,它的唯一目的是设置和获取对象实例,然后将这个类传递给可能需要它中的内容的其他类。

代码语言:javascript
复制
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中:

代码语言:javascript
复制
// 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:

代码语言:javascript
复制
class User {

    protected $container = null;

    public function __construct( DIContainer $container )
    {
        $this->container = $container;
    }

    public function getRows()
    {
        $rows = $this->container->database->getRows( '...' );
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-01-12 12:06:03

您正在寻找php中的自动加载。这一主题已经讨论过,并有一些很好的解释这里

简单地说,在文件开始时(声明名称空间之后),可以告诉php类依赖于什么。

代码语言:javascript
复制
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/"} }

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34743028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档