我正在一个Silex项目中,我使用类进行不同的处理:
$connection = new Connection($app);
$app->match('/connection', function () use ($app, $connection) {
$connexion->connectMember();
return $app->redirect($app['url_generator']->generate('goHome'));
})->method('GET|POST')->bind('doConnection');
在我的类"连接"的函数"connectMember()"中,我有:
[...]
if($isMember){
[...]
}else{
return $this->_app['twig']->render(
'message.twig',
array('msg' => "This member does not exist.", 'class' => 'Warning'));
}
[...]
但是渲染 () 方法不起作用。我想要显示的错误消息没有显示,而是启动了"$ app-> 重定向 (...)"。
如何让我的类使用当前对象 Silex''Application ?是否有更好的方法将自定义类绑定到 Silex 应用程序的实例?
非常感谢您的回答!
版本 : 添加信息
如果我使用 :
return $connexion->connectMember();
将显示错误消息。但这不是一个好的解决方案。"connection"类调用也使用此代码的其他类:
$this->_app['twig']->render(...).
如何使$ this->_app(存在于我的类中)对应于在我的控制器中创建的变量$app?
为 Connection
(或Connexion
??)类创建一个服务并注入应用程序:
use Silex'Application;
class Connection
{
private $_app;
public function __construct(Application $app)
{
$this->_app = $app;
}
// ...
}
$app['connection'] = function () use ($app) {
return new Connection($app); // inject the app on initialization
};
$app->match('/connection', function () use ($app) {
// $app['connection'] executes the closure which creates a Connection instance (which is returned)
return $app['connection']->connectMember();
// seems useless now?
return $app->redirect($app['url_generator']->generate('goHome'));
})->method('GET|POST')->bind('doConnection');
在 silex 和 pimple 的文档中阅读更多关于它的信息(pimple 是 silex 使用的容器)。
如果你使用$app->share(...)进行依赖注入,你可以设置这样的东西(它是伪代码):
<?php
namespace Foo;
use Silex'Application as ApplicationBase;
interface NeedAppInterface {
public function setApp(Application $app);
}
class Application extends ApplicationBase {
// from 'Pimple
public static function share($callable)
{
if (!is_object($callable) || !method_exists($callable, '__invoke')) {
throw new InvalidArgumentException('Service definition is not a Closure or invokable object.');
}
return function ($c) use ($callable) {
static $object;
if (null === $object) {
$object = $callable($c);
if ($object instanceof NeedAppInterface) {
// runtime $app injection
$object->setApp($c); // setApp() comes from your NeedAppInterface
}
}
return $object;
};
}
}
现在这样做:
$app['mycontroller'] = $app->share(function() use ($app) {
return new ControllerImplementingNeedAppInterface();
});
调用$app['我的控制器']时会自动设置$app!
PS :如果你不想使用 ->share() 试试用 __invoke($app),因为 ''Pimpple::offsetGet() 调用它:p