Silex,使用闭包安装多个控制器提供程序

时间:2014-02-26 06:57:24

标签: closures silex

我正在尝试Silex并且我遇到了一些问题,或者我可能会说,更不方便......

我正在尝试从2个单独的yaml文件加载2个路由,但由于某种原因,挂载($app->mount(...))不适用于闭包。

以下是一些代码:

// load configuration
$loader->load('core.yml');
$loader->load('api.yml');


function bla($app, $container, $key) {
    $myApp = $app['controllers_factory'];

    foreach ($container->getExtensionConfig('routes')[$key] as $name => $route) {
        $controller = $myApp->match($route['pattern'], $route['controller']);
        $controller->method($route['requirements']['_method']);
        $controller->bind($name);
    }
    return $myApp;
}

$app->mount('/core', bla($app, $container, 0));
$app->mount('/api', bla($app, $container, 1));

这很有效。

如果我对闭包执行完全相同的操作,那么什么是行不通的:

$app->mount('/core', function ($app, $container, $key) {
    return $app['controllers_factory'];
});

给出以下错误:

LogicException: The "mount" method takes either a ControllerCollection or a ControllerProviderInterface instance.

但是

var_dump($app['controllers_factory']);

吐出Silex\ControllerCollection类型的对象。

我显然错过了什么。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

问题

在第一个示例中,您正在挂载函数的结果。在第二个例子中,您正在安装函数本身。

函数bla()在调用时返回控制器集合。当你这样做

$app->mount('/core', bla($app, $container, 0));

首先执行该函数,然后挂载返回的ControllerCollection

但是当你做的时候

$app->mount('/core', function ($app, $container, $key) {...});

该功能未执行。它被视为一个物体并被安装。由于函数ittelf不是ControllerCollectionControllerProviderInterface,因此您会收到错误。

两个选择

使用PHP路由

这就是我喜欢的方式。我不知道这是否是“Silex方式”,但对我来说效果很好。

您可以像这样挂载每个控制器集合:

$app->mount('/core', include 'controllers/core.php');
$app->mount('/api', include 'controllers/api.php');

每个控制器集合都在controllers文件夹中的单独文件中。所以api.php可能看起来像这样:

$controllers = $app['controllers_factory'];

$controllers->get('/version', function() use ($app) {
  // do whatever you want
  return 'version 1.2';
});

return $controllers;

甚至可能有一种方法可以使用YML加载器并将路由保存在yml文件中,但我不喜欢混合使用yml和php。为什么在使用两种技术时可以使用两种技术。

一种更高级的方式

看看this article。他的技术比我的更优雅,但也更复杂。对于大型项目来说,这可能更好。也许它会对你更好。