Как установить для определения PHP-DI значение PHPActiveRecord Connection?

Я новичок в внедрении зависимостей и использую следующие инструменты в своем проекте 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, и вы готовы к работе.

Сейчас я пытаюсь внедрить свои модели ActiveRecord в контроллеры, используя аннотации, такие как документация PHP-DI:

<?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 в этой ситуации. В случаях, когда нет четко определенных "точек инжекции", таких как инъекции конструктора и / или сеттера.

Если вы думаете, что я не совсем понимаю свою проблему, спросите меня, и я могу предоставить больше информации.

1 ответ

Решение

Боюсь, что нет хорошего решения вашей проблемы. Как вы сказали, PHPActiveRecord - это библиотека, построенная на одиночных и статических методах, которая плохо сочетается с внедрением зависимостей.

Но в основном, в вашем примере, вы пытаетесь внедрить модельный объект. Это (обычно) то, что вы никогда не должны делать. Вы должны ввести значения конфигурации или "сервисы" или любые объекты, общие для всего приложения, но не модели.

Модели выбираются из базы данных в зависимости от запросов (например, ID). Поэтому нет смысла вставлять пользователя в контроллер, поскольку по определению пользователей много (их целая таблица).

Что обычно делается, так это вводит объект / сервис, который обеспечивает способ извлечения моделей. Эти объекты иногда называют "хранилищем" в зависимости от библиотеки. Итак, это выглядит так:

  • вы вводите репозиторий UserRepository в контроллер (или объект Database, или EntityManager, или что бы то ни было)
  • Затем вы используете этот объект, чтобы выбрать любого пользователя внутри контроллера.

Технически, проблема, с которой вы здесь сталкиваетесь, заключается в (я думаю), что PHP-DI пытается создать новый пользовательский экземпляр (используя new) и PHPActiveRecord пытается автоматически подключиться к базе данных. Поскольку ничего не было настроено для базы данных (я полагаю), PHPActiveRecord завершается ошибкой.

Короче, что делать?

  • держите инициализацию PHPActiveRecord вне PHP-DI, так как он должен выполняться при каждом запросе
  • создавать / извлекать /… модели способом PHPActiveRecord, то есть статическими методами. PHP-D я не могу помочь там

Если вы хотите сбросить PHPActiveRecord, возможно, взгляните на Doctrine (который более сложный) или Propel (который должен быть ближе к тому, что делает PHPActiveRecord).

Другие вопросы по тегам