duanguane1670 2015-06-26 21:14
浏览 66
已采纳

使用Restler 3的依赖注入容器Scope时,将参数值传递给__construct()

I've got an application which uses the DIC Pimple to manage dependency injection; that works great when calling certain methods via command line or internally. However, once I try to call them by an API provided by Restler, it begins throwing 500 errors due to the fact that the __construct() was not given the needed parameters. (Note that methods inside a class that has no __construct() or requires no constructor parameters work just fine via API.)

I am trying to use Restler's internal DIC called Scope, which isn't really working so well. Case in point, I've got something like this in index.php:

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

The issue is that \Noodlehaus\Config requires the path to a JSON encoded configuration file upon instantiation. Within my application this has already been handled within Pimple.

When using my Main loader object, which instantiates Pimple and populates the container with needed dependencies, I am able to call the same method directly via CLI without any problems like so:

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

I imagine that the capability for this is there within Scope, but without an example or some documentation I have not been able to figure it out. And frankly, I'd like to limit my usage of Scope to as little as possible due to the fact that it is built upon a singleton pattern, which sort of defeats the whole idea of using dependency injection in the first place.

Really I'd like to be able to have Restler access the methods in my classes and instantiate them using Pimple. That would be a score for integration.

Edit:

I have been directed to this bug/feature request for support for an external dependency injection container in Restler. The author has implemented it in the upcoming RC6.

I can't say that I am entirely sure about using it yet though. There is an example shown here in a related bug.

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

The author states that an external DIC should be used like so:

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

I am almost there, it is nearly working. I believe the issue now has something to do with Restler dependencies not being loaded by my DIC. As mentioned previously, I am using the dependency injection container Pimple. I have an initialization class called Main in which I instantiate Pimple, set up dependencies, load configuration file, etc.

Here are relevant portions of 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();

        ...
        }
    ...
    }

This is my 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();

?>

This is the error (I can provide stack trace is that will be useful:)

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

Thanks for any help that can be provided!

Edit 2:

The problem seems to go deeper than simply not having the dependencies within Pimple. I suspect the issue is related to a difference in the structure of DIC's:

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

Edit 3: These are the new errors after implementing Luracast's suggestion:

[$] 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

It is probably worthwhile to note that I have implemented a different dependency injection container, one called PHP-DI. This one has syntax that is closer to that of Scope, so I figured it would be simpler to get it working with Restler. However, I am getting the exact same errors thrown with both of them.

  • 写回答

2条回答 默认 最新

  • doutuohan6606 2015-07-04 19:54
    关注

    Thanks to Luracast, I do have the solution now! Fortunately Restler RC6 PHP-DI are perfectly compatible once they are integrated correctly. The problem was, no surprise, one of my own making.

    It was all a matter of the namespace. I had originally defined the namespace Kiosk at the beginning of my index.php. Luracast suggest keeping it within the root namespace.

    This is the current working 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();
    
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序