如何将PHP-DI定义设置为PHPActiveRecord Connection?

时间:2014-08-12 20:38:58

标签: php activerecord dependency-injection containers php-di

我是关于依赖注入的初学者,我在PHP 5.5.9(在Apache2和MySql下)项目中使用以下工具:

我的所有课程都是由作曲家自动加载的。

通过阅读它的文档并运行它与自动装配,注释和配置相关的示例,我已经对PHP-DI定义有了一些了解,并且我已经将它用于我自己的类,但现在我被困在如何设置供应商库,例如PHPActiveRecord。

通常使用PHPActiveRecord,您只需要定义这样的连接设置:

$cfg = ActiveRecord\Config::instance();
$cfg->set_model_directory('/path/to/your/model_directory');
$cfg->set_connections(
    ['development' => 'mysql://username:password@localhost/database_name']
);

或者这个:

ActiveRecord\Config::initialize(function($cfg)
{
    $cfg->set_model_directory('/path/to/your/model_directory');
    $cfg->set_connections(['development' =>
    'mysql://username:password@localhost/database_name']);
});

最后,你的模型应该扩展ActiveRecord \ Model,你已经准备好了。

现在我试图通过使用PHP-DI文档建议的注释将我的ActiveRecord模型注入控制器:

<?php

    namespace Controller;

    use Model\User;

    class TestController
    {
        /**
        * @Inject
        * @var User
        */
        protected $user;

        public function index()
        {
            echo $this->user->retrieveStatus();
        }
    }

我收到错误:

Fatal error: Uncaught exception 'ActiveRecord\DatabaseException' with message 'Empty connection string' in /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Connection.php:105 

Stack trace: 
#0 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/ConnectionManager.php(33): ActiveRecord\Connection::instance(NULL) 
#1 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(117): ActiveRecord\ConnectionManager::get_connection(NULL) 
#2 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(93): ActiveRecord\Table->reestablish_connection(false) 
#3 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(74): ActiveRecord\Table->__construct('Model\User') 
#4 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Model.php(749): ActiveRecord\Table::load('Model\User') 
#5 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Model.php(262): ActiveRecord\Model::table() 
#6 [internal function]: ActiveRecord\Model- in /home/ubuntu/workspace/vendor/mnapoli/php-di/src/DI/Definition/Resolver/ClassDefinitionResolver.php on line 276

看起来,没有为ActiveRecord提供字符串连接。

我只是认为我需要一个正确的文件配置设置(我认为是DI \ factory)来根据上面的连接定义返回一个ActiveRecord \ Config实例。

让我担心的另一点是,PHPActiveRecord在它的API中有相当数量的Singletons和静态函数,据我所知,由于有点紧耦合问题,它被认为是一种反模式,对DI的管理似乎没有好处在这种情况下,没有明确定义的“注入点”,例如构造函数和/或setter注入。

如果您认为我对我的问题不够清楚,请告诉我,我可以提供更多信息。

1 个答案:

答案 0 :(得分:0)

我担心你的问题没有一个好的解决方案。正如您所说,PHPActiveRecord是一个基于单例和静态方法的库,它与依赖注入不能很好地混合。

但主要是,在您的示例中,您尝试注入模型对象。这是(通常)你永远不应该做的事情。您应该注入配置值或&#34;服务&#34;或者在整个应用程序中共享任何对象,而不是模型。

根据查询(例如ID)从数据库中提取模型。因此,在控制器中注入用户是没有意义的,因为根据定义,许多用户(其中包含了整个表格)。 / p>

通常做的是注入提供检索模型的方法的对象/服务。这些对象有时被称为&#34; 存储库&#34;取决于图书馆。所以它是这样的:

  • 您将UserRepository注入控制器(或数据库对象,或EntityManager,或其他任何东西)
  • 然后使用该对象获取控制器中所需的任何用户

从技术上讲,你遇到的问题是(我认为)PHP-DI尝试创建一个新的User实例(使用new)和PHPActiveRecord尝试自动连接到数据库。由于没有为数据库配置(我猜),PHPActiveRecord失败。

总之,该怎么做?

  • 将PHPActiveRecord的初始化保留在PHP-DI之外,因为它需要在每个请求上执行
  • 通过PHPActiveRecord方式创建/获取/ ...模型,即静态方法。 PHP-DI无法帮助

如果要转储PHPActiveRecord,可以查看Doctrine(更复杂)或Propel(它应该更接近PHPActiveRecord所做的那样)。