首先我想说,我发现Symfony2是一个令人惊叹的框架,所以我正在使用FOSRestBundle等创建一个RESTful API。但我的目标不是只支持API中的一个Symfony2应用程序,我需要多个其他symfony1应用程序来与API交互。我确实可以使用cURL来实现这一点,只需向API发出简单的http请求,但由于API与所有其他项目总是在同一台服务器上,我希望通过它的内核直接处理API请求(因此没有cURL)。当然,这带来了惊人的速度提升,同时也减少了资源的使用。
因此,为了实现这一点,我首先考虑简单地从目的地要求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)。
我真的希望有人能帮我!
Steffen
我已经设法使其工作:)我检查了路由文件,发现请求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();
}
}
当然,这只是一个工作的例子,我将以更好的方式实施这一战略。好吧,找同样答案的人真好看!
编辑:
我认为最好的方法是有两个自动加载器,一个用于主sf2应用程序,另一个用于API。这样,两个项目的供应商都可以自动加载。