Передайте значения параметров в __construct() при использовании контейнера внедрения зависимостей Restler 3 Scope

У меня есть приложение, которое использует DIC Pimple для управления внедрением зависимостей; это прекрасно работает при вызове определенных методов через командную строку или внутри. Однако, как только я пытаюсь вызвать их с помощью API, предоставленного Restler, он начинает выдавать 500 ошибок из-за того, что __construct() не были заданы необходимые параметры. (Обратите внимание, что методы внутри класса, который не имеет __construct() или не требует параметров конструктора, прекрасно работают через API.)

Я пытаюсь использовать внутренний DIC Restler под названием Scope, который на самом деле работает не так хорошо. Например, у меня есть что-то вроде этого в index.php:

Scope::register('Kiosk\\Drone\\Drone', function () { 
    return new Kiosk\Drone\Drone(Scope::get('\\Noodlehaus\\Config')); 
}); 

Проблема в том, что для \Noodlehaus\Config требуется путь к файлу конфигурации в формате JSON при создании экземпляра. В моем приложении это уже было обработано в Pimple.

При использовании моего объекта-загрузчика Main, который создает экземпляр Pimple и заполняет контейнер необходимыми зависимостями, я могу вызывать тот же метод напрямую через CLI без каких-либо проблем, например:

$file = __DIR__ . "/config.json";
$main = new Main($file);
$d = new Kiosk\Drone\Drone($main->c['config']);

Я предполагаю, что возможность для этого есть в Scope, но без примера или какой-либо документации я не смог понять это. И, честно говоря, я бы хотел как можно меньше использовать Scope из-за того, что он построен на одноэлементном шаблоне, который как бы опровергает всю идею использования внедрения зависимостей в первое место.

На самом деле я хотел бы иметь возможность Restler получать доступ к методам в моих классах и создавать их экземпляры с помощью Pimple. Это будет баллом за интеграцию.

Редактировать:

Меня перенаправили на этот запрос об ошибке/функции для поддержки контейнера внедрения внешних зависимостей в Рестлер. Автор реализовал это в грядущей RC6.

Хотя я не могу сказать, что полностью уверен в его использовании. Пример показан здесь в соответствующей ошибке.

$objectManager = new MyOwnDependencyInjectionContainer();
Scope::$resolver = function ($className) use ($objectManager) {
    return $context->get($className);
};
$r->addAPIClass('MyOwnApiClass');

Автор утверждает, что внешний DIC следует использовать следующим образом:

Scope::$resolver = function ($className) use ($context) {
    return $context->getByType($className);
};

Я почти там, он почти работает. Я считаю, что теперь проблема как-то связана с зависимостями Restler, которые не загружаются моим DIC. Как упоминалось ранее, я использую контейнер внедрения зависимостей Pimple. У меня есть класс инициализации под названием Main, в котором я создаю экземпляр Pimple, устанавливаю зависимости, загружаю файл конфигурации и т. д.

Вот соответствующие части Main.php:

class Main {

    private $configFile;
    public $c; // a dependency injection container

    public function __construct($configFile=null){
        $this->configFile = $configFile;
        //create DIC
        $this->c = new Container();

        ...
        }
    ...
    }

Это мой index.php:

<?php

namespace Kiosk;

use Luracast\Restler\Scope;
use Luracast\Restler\Restler;

require_once __DIR__.'/vendor/autoload.php';

$file = __DIR__ . "/config.json";

$main = new Main($file);

$c = $main->c;
Scope::$resolver = function ($className) use ($c) { 
    return $c[$className];
};

$r = new Restler(true,true);
$r->addAPIClass('Luracast\\Restler\\Resources');
$r->addAPIClass('Kiosk\\Drone\\Drone','drone');
$r->handle();

?>

Это ошибка (я могу предоставить трассировку стека, это будет полезно :)

PHP Fatal error:  Uncaught exception 'InvalidArgumentException' with   message 'Identifier "Luracast\Restler\Format\JsonFormat" is not defined.' in     /var/www/kitchenkiosk.co/public_html/api/vendor/pimple/pimple/src/Pimple/Container.php:95

Спасибо за любую помощь, которая может быть предоставлена!

Редактировать 2:

Проблема, похоже, глубже, чем просто отсутствие зависимостей внутри Pimple. Я подозреваю, что проблема связана с разницей в структуре DIC:

PHP Fatal error:  Uncaught exception 'InvalidArgumentException' with     message 'Identifier "Luracast\Restler\Format\JsonFormat" is not defined.'     in         /var/www/public_html/api/vendor/pimple/pimple/src/Pimple/Container.php:95
Stack trace:
#0 /var/www/public_html/api/index.php(17): Pimple\Container-        >offsetGet('Luracast\\Restle...')
#1  /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/S cope.php(108): Kiosk\{closure}('Luracast\\Restle...')
#2  /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php(389): Luracast\Restler\Scope::get('JsonFormat')
#3 /var/www/public_html/api/index.php(21): Luracast\Restler\Restler->setSupportedFormats('JsonFormat')
#4 {main}
thrown in /var/www/public_html/api/vendor/pimple/pimple/src/Pimple/Container.php on line 95

Редактировать 3: Это новые ошибки после реализации предложения Luracast:

[$] PHP Warning:  PDO::__construct() expects at least 1 parameter, 0 given in /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php on line 711
[$] PHP Stack trace:
[$] PHP   1. {main}() /var/www/public_html/api/index.php:0
[$] PHP   2. Luracast\Restler\Restler->handle() /var/www/public_html/api/index.php:27
[$] PHP   3. Luracast\Restler\Restler->call() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:304
[$] PHP   4. call_user_func_array:{/var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045}() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   5. Luracast\Restler\Resources->get() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   6. Luracast\Restler\Resources->_parameter() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:327
[$] PHP   7. Luracast\Restler\Resources->_model() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:553
[$] PHP   8. PDO->__construct() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:711
[$] PHP Warning:  get_object_vars() expects parameter 1 to be object, null given in /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php on line 713
[$] PHP Stack trace:
[$] PHP   1. {main}() /var/www/public_html/api/index.php:0
[$] PHP   2. Luracast\Restler\Restler->handle() /var/www/public_html/api/index.php:27
[$] PHP   3. Luracast\Restler\Restler->call() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:304
[$] PHP   4. call_user_func_array:{/var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045}() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   5. Luracast\Restler\Resources->get() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   6. Luracast\Restler\Resources->_parameter() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:327
[$] PHP   7. Luracast\Restler\Resources->_model() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:553
[$] PHP   8. get_object_vars() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:713
[$] PHP Warning:  Invalid argument supplied for foreach() in /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php on line 715
[$] PHP Stack trace:
[$] PHP   1. {main}() /var/www/public_html/api/index.php:0
[$] PHP   2. Luracast\Restler\Restler->handle() /var/www/public_html/api/index.php:27
[$] PHP   3. Luracast\Restler\Restler->call() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:304
[$] PHP   4. call_user_func_array:{/var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045}() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   5. Luracast\Restler\Resources->get() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Restler.php:1045
[$] PHP   6. Luracast\Restler\Resources->_parameter() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:327
[$] PHP   7. Luracast\Restler\Resources->_model() /var/www/public_html/api/vendor/luracast/restler/vendor/Luracast/Restler/Resources.php:553

Вероятно, стоит отметить, что я реализовал другой контейнер внедрения зависимостей, который называется PHP-DI. Его синтаксис ближе к Scope, поэтому я решил, что будет проще заставить его работать с Restler. Тем не менее, я получаю одни и те же ошибки с обоими из них.


person Fliggerty    schedule 26.06.2015    source источник


Ответы (2)


Позвольте мне попытаться найти более простое решение

<?php

use Luracast\Restler\Scope;
use Luracast\Restler\Restler;

require_once __DIR__.'/vendor/autoload.php';

$file = __DIR__ . "/config.json";

$main = new Main($file);

$c = $main->c;

Scope::register('Kiosk\\Drone\\Drone', function () use ($c) { 
    return $c['Kiosk\Drone\Drone']; 
}); 

$r = new Restler(true,true);
$r->addAPIClass('Luracast\\Restler\\Resources');
$r->addAPIClass('Kiosk\\Drone\\Drone');
$r->handle();
person Arul Kumaran    schedule 29.06.2015
comment
Спасибо за ваше предложение. К сожалению, у меня все еще есть трудности с этим. Мой файл index.php выглядит почти так же, как вы предложили, но теперь он выдает МНОГО ошибок... все они, похоже, связаны с невозможностью передать параметры в зависимости. Я отредактировал свой исходный вопрос, включив в него журналы ошибок. - person Fliggerty; 01.07.2015

Благодаря Luracast, теперь у меня есть решение! К счастью, Restler RC6 PHP-DI полностью совместимы, если они правильно интегрированы. Неудивительно, что проблема возникла по моей вине.

Все дело было в пространстве имен. Изначально я определил пространство имен Kiosk в начале файла index.php. Luracast предлагает оставить его в корневом пространстве имен.

Это текущий рабочий index.php:

<?php

use Luracast\Restler\Scope;
use Luracast\Restler\Restler;
use Kiosk\Main;
use Kiosk\Drone\Drone;

require_once __DIR__.'/vendor/autoload.php';

$file = __DIR__ . "/config.json";

$main = new Main($file);

$c = $main->c;

Scope::register('Kiosk\\Drone\\Drone', function () use ($c) {
    return new DataTable($c->get('config'), $c->get('logger'));
});

$r = new Restler();
$r->addAPIClass('Luracast\\Restler\\Resources');
$r->addAPIClass('Kiosk\\Drone\\Drone','drone');
$r->addAuthenticationClass('Kiosk\\System\\TokenAuth');
$r->handle();

?>
person Fliggerty    schedule 04.07.2015