Symfony 2 - 处理服务中的内核请求(来自其他应用程序)

时间:2013-12-02 09:05:40

标签: php symfony curl request kernel

首先我想说我发现Symfony2是一个很棒的框架,所以我用FOSRestBundle等创建了一个RESTful API。但是我不打算只用API支持一个symfony2应用程序,我还需要其他多个symfony2应用程序与API交互。我确实可以通过使用cURL来做这个,只是对API发出简单的http请求,但是因为API总是与所有其他项目在同一台服务器上,我想通过它的内核直接处理API请求(所以没有卷曲)。这带来了惊人的速度提升,也减少了对资源的使用。

所以,为了实现这一点,我首先想到的只是从目的地那里要求AppKernel,就像这样:

require_once '/path/to/external/AppKernel.php';

然后我会创建一个AppKernel实例并在这里处理“子请求”。但是,我立即得到了错误,说有些捆绑包无法加载等,这是合乎逻辑的,因为我只需要AppKernel文件,而不是它的依赖项。所以我包含了API项目的自动加载器(/app/autoload.php),但这并没有解决问题,我得到了与重新声明的类/函数等相关的错误。

这可能是这样的:

require_once '/path/to/external/AppKernel.php';
$class = 'Namespace\AppKernel';

// I tried this, but this does not work...
$loader = require_once $path . '/autoload.php';

/**
  * @var HttpKernel $kernel
  */
$kernel = new $class('dev', true);

// $request contains a custom Request object created with 'Request::create()'
$response = $kernel->handle($request);
$response->send();

$kernel->terminate($request, $response);

return $response;

我认为通过AppKernel尝试处理它我做错了,也许有人知道更好的方法来调用外部Symfony2项目(没有cURL)。

我真的希望有人可以帮助我!

斯特芬

1 个答案:

答案 0 :(得分:0)

我已经设法让它工作了:)我检查了路由文件,并看到请求缺少请求uri前面的正斜杠(/)。这解释了404未找到。所以我现在正在实现KernelRequestHandler实现:

class KernelRequestHandler implements RequestHandlerInterface
{
    private static $kernel;

    /**
     * Get ApiKernel instance
     *
     * @param $class
     * @return mixed
     */
    public function getKernel($class)
    {
        if (!self::$kernel) {
            self::$kernel = new $class('prod', true);
        }

        return self::$kernel;
    }

    /**
     * @param Request $request
     * @param array $endpoints
     * @return mixed
     * @throws InvalidConfigurationException
     */
    public function handle(Request $request, array $endpoints)
    {
        require_once $endpoints['kernel']['path'];

        if (!isset($endpoints['kernel']['class'])) {
            throw new InvalidConfigurationException(sprintf("No class name found for instantiating kernel. Client: '%s'", $this->getName()));
        }

        $class = $endpoints['kernel']['class'];

        $path = realpath(dirname($endpoints['kernel']['path']));

        // Get Class Loader
        $loader = $_GLOBALS['loader'];

        // Add src folder to fallback dirs
        $loader->add(null, array(realpath($path . '/../src')));

        $class = '\ApiKernel';

        /**
         * @var Kernel $kernel
         */
        $kernel = $this->getKernel($class);

        $response = $kernel->handle($request);

        return $response->getContent();
    }
}

当然,这只是一个有效的例子,我将以更好的方式实施这一策略。嗯,好好期待那个寻找相同答案的人!

编辑:

我认为最好的方法是拥有2个自动加载器,一个用于主sf2应用程序,另一个用于API。这样两个项目的供应商都可以自动加载。