0

我是一个依赖注入的初学者,我在我的 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 中有相当多的单例和静态函数,据我所知,由于有点紧密的耦合问题,它被认为是一种反模式,一旦出现这种情况,对 DI 的管理似乎没有好处在没有明确定义的“注入点”的情况下,例如构造函数和/或 setter 注入。

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

4

1 回答 1

0

恐怕您的问题没有好的解决方案。正如您所说,PHPActiveRecord 是一个建立在单例和静态方法上的库,不能很好地与依赖注入混合。

但主要是,在您的示例中,您正在尝试注入模型对象。那是(通常)你不应该做的事情。您应该注入配置值或“服务”或在整个应用程序中共享的任何对象,而不是模型。

根据查询(例如 ID)从数据库中获取模型。所以在控制器中注入一个用户是没有意义的,因为根据定义有很多用户(他们有一个完整的表)。

通常所做的是注入提供检索模型的方法的对象/服务。这些对象有时被称为“存储库”,具体取决于库。所以它是这样的:

  • 您将 UserRepository 注入控制器(或 Database 对象,或 EntityManager,或其他任何东西)
  • 然后,您使用该对象在控制器中获取您想要的任何用户

从技术上讲,您在这里遇到的问题是(我认为)PHP-DI 试图创建一个新的用户实例(使用new)和 PHPActiveRecord 试图自动连接到数据库。由于没有为数据库配置任何内容(我猜),PHPActiveRecord 失败。

简而言之,该怎么办?

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

如果你想转储 PHPActiveRecord,也许看看 Doctrine(更复杂)或Propel(应该更接近 PHPActiveRecord 所做的)。

于 2014-08-12T21:38:57.327 回答