Silex ControllerCollection 未级联 __call 到其他 ControllerCollection
Silex ControllerCollection not cascading __call to fellow ControllerCollection
本周在使用 Silex、Routes 和 ControllerCollection
class 时,我 运行 遇到了以下问题:
我们正在开发的一些插件将自身附加到对象,将路由添加到它们在管理界面中的表示。这导致路线构建看起来像(断开):
$admin = $app['controllers_factory'];
$app->mount('/admin', $admin);
$user = $app['controllers_factory'];
$admin->mount('/user', $user);
$user->get('/', function() { return 'User List'; })
->bind('admin.user.list');
$user->get('/new', function() { return 'New User'; })
->bind('admin.user.new');
$user_detail = $app['controllers_factory'];
$user->mount('/{id}', $user_detail);
$user->assert('id', '\d+');
$user_detail->get('/', function($id) {
return "User: $id ";
})
->bind('admin.user.detail');
$user_extension = $app['controllers_factory'];
$user_detail->mount('/extension/{extension_name}', $user_extension);
$user_extension->get('/', function($id, $extension_name) {
return "User: $id\nExtension: $extension_name";
})
->bind('admin.user.extension.view');
我 运行 遇到的问题是,虽然调用 $app['url_generator']->generate('admin.user.edit', array('id' => 's2'));
会使用户 ID (\d+
) 的断言失败,但调用 $app['url_generator']->generate('admin.user.extension.view', array('id' => 's2', 'extension_name' => 'something'));
不会.分别访问它们的 URL 也是如此:/admin/user/s2
(失败)和 /admin/user/s2/extension/something/
(成功)。
before
、after
、value
、convert
和 require
[http/s] 方法表现出相同的行为出色地。这是预期的行为吗?该值是 t运行sferred 从第一次挂载到扩展视图时很好,并且生成器可以流畅地处理它,但是 assert
的行为并不像预期的那样。
我做错了什么?
问题出在ControllerCollection对__call()
的实现上。 ControllerCollection 首先检查它是否支持方法:
if (!method_exists($this->defaultRoute, $method)) {
throw new \BadMethodCallException(sprintf('Method "%s::%s" does not exist.', get_class($this->defaultRoute), $method));
}
然后它将调用级联到它的控制器(毕竟它是一个控制器集合):
foreach ($this->controllers as $controller) {
if ($controller instanceof Controller) {
call_user_func_array(array($controller, $method), $arguments);
}
}
问题在于 instanceof
检查,它没有考虑 ControllerCollection
的额外实例。这在网络上几乎没有静态,所以我认为这要么是预期的行为,要么不是许多人的标准程序。
解决方法就像将 || $controller instanceof ControllerCollection
添加到 if
条件一样简单,我有两个解决方案可供其他任何期待此行为的人使用:
Extended Class for Silex Controller Collection
Either/Or。我们拭目以待。
本周在使用 Silex、Routes 和 ControllerCollection
class 时,我 运行 遇到了以下问题:
我们正在开发的一些插件将自身附加到对象,将路由添加到它们在管理界面中的表示。这导致路线构建看起来像(断开):
$admin = $app['controllers_factory'];
$app->mount('/admin', $admin);
$user = $app['controllers_factory'];
$admin->mount('/user', $user);
$user->get('/', function() { return 'User List'; })
->bind('admin.user.list');
$user->get('/new', function() { return 'New User'; })
->bind('admin.user.new');
$user_detail = $app['controllers_factory'];
$user->mount('/{id}', $user_detail);
$user->assert('id', '\d+');
$user_detail->get('/', function($id) {
return "User: $id ";
})
->bind('admin.user.detail');
$user_extension = $app['controllers_factory'];
$user_detail->mount('/extension/{extension_name}', $user_extension);
$user_extension->get('/', function($id, $extension_name) {
return "User: $id\nExtension: $extension_name";
})
->bind('admin.user.extension.view');
我 运行 遇到的问题是,虽然调用 $app['url_generator']->generate('admin.user.edit', array('id' => 's2'));
会使用户 ID (\d+
) 的断言失败,但调用 $app['url_generator']->generate('admin.user.extension.view', array('id' => 's2', 'extension_name' => 'something'));
不会.分别访问它们的 URL 也是如此:/admin/user/s2
(失败)和 /admin/user/s2/extension/something/
(成功)。
before
、after
、value
、convert
和 require
[http/s] 方法表现出相同的行为出色地。这是预期的行为吗?该值是 t运行sferred 从第一次挂载到扩展视图时很好,并且生成器可以流畅地处理它,但是 assert
的行为并不像预期的那样。
我做错了什么?
问题出在ControllerCollection对__call()
的实现上。 ControllerCollection 首先检查它是否支持方法:
if (!method_exists($this->defaultRoute, $method)) {
throw new \BadMethodCallException(sprintf('Method "%s::%s" does not exist.', get_class($this->defaultRoute), $method));
}
然后它将调用级联到它的控制器(毕竟它是一个控制器集合):
foreach ($this->controllers as $controller) {
if ($controller instanceof Controller) {
call_user_func_array(array($controller, $method), $arguments);
}
}
问题在于 instanceof
检查,它没有考虑 ControllerCollection
的额外实例。这在网络上几乎没有静态,所以我认为这要么是预期的行为,要么不是许多人的标准程序。
解决方法就像将 || $controller instanceof ControllerCollection
添加到 if
条件一样简单,我有两个解决方案可供其他任何期待此行为的人使用:
Extended Class for Silex Controller Collection
Either/Or。我们拭目以待。