我正在尝试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
类型的对象。
我显然错过了什么。
感谢您的帮助。
答案 0 :(得分:2)
在第一个示例中,您正在挂载函数的结果。在第二个例子中,您正在安装函数本身。
函数bla()
在调用时返回控制器集合。当你这样做
$app->mount('/core', bla($app, $container, 0));
首先执行该函数,然后挂载返回的ControllerCollection
。
但是当你做的时候
$app->mount('/core', function ($app, $container, $key) {...});
该功能未执行。它被视为一个物体并被安装。由于函数ittelf不是ControllerCollection
或ControllerProviderInterface
,因此您会收到错误。
这就是我喜欢的方式。我不知道这是否是“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。他的技术比我的更优雅,但也更复杂。对于大型项目来说,这可能更好。也许它会对你更好。