Symfony 2 - 处理服务中的内核请求(来自另一个应用程序) [英] Symfony 2 - Handle a Kernel request (from another app) inside a service

查看:368
本文介绍了Symfony 2 - 处理服务中的内核请求(来自另一个应用程序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

First I would like to say I find Symfony2 an amazing framework, so I'm creating a RESTful API with it using FOSRestBundle etc. But I'm not aiming for supporting only one symfony2 application with the API, I need multiple other symfony2 applications to interact with the API. I could indeed do this with the use of cURL and just make plain http requests to the API, but because the API is always on the same server as all the other projects I would like to handle the API requests directly trough it's Kernel (so no cURL). This comes with an amazing speed boost ofcourse and also less use of resources.

因此,为了使这一切,我首先想到只需要从目的地的AppKernel,所以:

So, to make this happen, I first thought about simply requiring the AppKernel from it's destination, like so:

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

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

Then I would create an instance of AppKernel and handle the "sub-request" in here. But then, I instantly got errors, saying some bundles could not be loaded etc. which is logical because I only required the AppKernel file, not it's dependencies. So I included the autoloader of the API project (/app/autoload.php), but this did not resolve the problems, I got errors related to redeclared classes/functions etc.

这将给出这样的:

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)。

I think I'm doing it all wrong with trying to handle it trough the AppKernel, maybe someone knows a better way to make a call to a external Symfony2 project (without cURL).

我真的希望有人能帮助我!

I really hope somebody could help me out!

Steffen

推荐答案

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

I've managed to get it working :) I checked the routing files, and saw that the request was missing a forward slash (/) infront of the request uri. That explained the 404 not found. So my working KernelRequestHandler implementation is now:

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();
    }
}

当然这只是一个工作示例,将以更好的方式实施这一战略。好,看看一个寻找同样的答案!

Ofcourse this is just a working example, I'm going to implement this strategy in a better way. Well, good look to the one looking for the same answer!

编辑:

是有2个自动加载器,一个用于主要的sf2应用程序,一个用于这种情况下的API。这样,两个项目的供应商都会自动加载。

I think the best way is to have 2 autoloaders, one for the main sf2 application and one for the API in this case. This way the vendors of both projects get autoloaded.

这篇关于Symfony 2 - 处理服务中的内核请求(来自另一个应用程序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆