简体   繁体   English

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

[英]How to set PHP-DI definition to PHPActiveRecord Connection?

I'm a beginner about Dependency Injection and I'm using the following tools into my PHP 5.5.9 (under Apache2 and MySql) project: 我是有关依赖注入的初学者,并且在我的PHP 5.5.9(在Apache2和MySql下)项目中使用了以下工具:

All my classes use to be autoloaded by composer. 我所有的类都曾经被作曲家自动加载。

I already got some insight about PHP-DI Definitions by reading it's docs and running it's examples related to autowiring , annotations and config and I've been put it to work with my own classes, but now I'm stuck about how to set vendor libraries such as PHPActiveRecord. 通过阅读文档并运行与自动装配,注释和配置有关的示例,我已经对PHP-DI定义有了一些了解,并且已经将其与我自己的类一起使用,但是现在我对如何设置供应商一事无所适从库,例如PHPActiveRecord。

Usually to use PHPActiveRecord all you need is to define connections settings like this: 通常要使用PHPActiveRecord,您所需要做的就是定义如下连接设置:

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

Or this: 或这个:

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

Finally your models should extends ActiveRecord\\Model and you're ready to go. 最后,您的模型应该扩展ActiveRecord \\ Model,您可以开始使用。

For now I'm trying to inject my ActiveRecord models into controllers by using annotations such as PHP-DI's documentation suggests: 现在,我正在尝试通过使用注释(例如PHP-DI的文档建议)将ActiveRecord模型注入控制器中:

<?php

    namespace Controller;

    use Model\User;

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

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

Here I got the error: 在这里我得到了错误:

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

As it seems, no string connection provided to ActiveRecord. 看来,没有字符串连接提供给ActiveRecord。

I just believe that I need a proper File Configuration setting (DI\\factory I think) to return a ActiveRecord\\Config instance based on the connection definitions above. 我只是相信我需要一个适当的文件配置设置(我认为DI \\ factory)才能根据上述连接定义返回ActiveRecord \\ Config实例。

Another point the bring me worries is that PHPActiveRecord have a considerable amount of Singletons and statics functions into it's API and as far as I know it's considered an anti-pattern due to kinda tight coupling issues and it seems no good to DI's management once in this cases there's no well defined "injection points" such as constructor and/or setter injections. 令我担心的另一点是,PHPActiveRecord的API中包含大量的Singleton和静态函数,据我所知,由于存在一些紧密的耦合问题,因此它被认为是反模式,对DI的管理而言,这似乎没有任何好处。情况下,没有明确定义的“注入点”,例如构造函数和/或setter注入。

If you think I'm not clear enough about my problem, aske me for and I can provide more info. 如果您认为我对我的问题还不够清楚,请向我询问,我可以提供更多信息。

I'm afraid there isn't a good solution for your problem. 恐怕您的问题没有很好的解决方案。 As you have said, PHPActiveRecord is a library built on singletons and static methods, that doesn't mix well with dependency injection. 如您所说,PHPActiveRecord是一个基于单例和静态方法构建的库,与依赖项注入不能很好地结合使用。

But mainly, in your example, you are trying to inject a model object. 但主要是在您的示例中,您尝试注入模型对象。 That's (usually) something you should never do. (通常)这是您永远不应该做的事情。 You should inject configuration values or "services" or whatever objects are shared throughout the application, but not models. 您应该注入配置值或“服务”或在整个应用程序中共享的任何对象,但不能注入模型。

Models are fetched from the database depending on queries (for example an ID). 根据查询(例如ID)从数据库中获取模型。 So it doesn't make sense to inject a user in the controller since by definition there are many users (there's a whole table of them). 因此,将用户注入到控制器中是没有意义的,因为根据定义,有很多用户 (有一个完整的表)。

What is usually done is inject the object/service that provides a way to retrieve the models. 通常要做的是注入提供一种检索模型的方法的对象/服务。 Those objects are sometimes called " repository " depending on the library. 根据库的不同,有时将这些对象称为“ 存储库 ”。 So it goes like this: 所以它是这样的:

  • you inject the UserRepository in the controller (or the Database object, or the EntityManager, or whatever it is) 您将UserRepository注入到控制器(或数据库对象,或EntityManager或其任何对象)中
  • you then use that object to fetch whichever user you want inside the controller 然后,您可以使用该对象来获取控制器内所需的任何用户

Technically, the problem you get here is (I think) PHP-DI trying to create a new User instance (using new ) and PHPActiveRecord trying to connect to the database automatically. 从技术上讲,您遇到的问题是(我认为)PHP-DI试图创建一个新的User实例(使用new )和PHPActiveRecord试图自动连接到数据库。 Since nothing was configured for the database (I guess), PHPActiveRecord fails. 由于没有为数据库配置任何内容(我想),因此PHPActiveRecord失败。

So in short, what to do? 简而言之,该怎么办?

  • keep the initialization of PHPActiveRecord out of PHP-DI since it needs to be executed on each request 将PHPActiveRecord的初始化保留在PHP-DI中,因为它需要在每个请求上执行
  • create/fetch/… models through PHPActiveRecord's way, ie static methods. 通过PHPActiveRecord的方式(即静态方法)创建/获取/…模型。 PHP-DI can't help there PHP-DI在那里无能为力

If you want to dump PHPActiveRecord, maybe have a look at Doctrine (which is more complex) or Propel (which should be closer to what PHPActiveRecord do). 如果要转储PHPActiveRecord,则可以看看Doctrine(更复杂)或Propel (应该更接近PHPActiveRecord的功能)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM