【问题标题】:Inject Silex $app in my custom class在我的自定义类中注入 Silex $app
【发布时间】:2013-10-24 12:16:49
【问题描述】:

我在一个 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');

在我的类“Connection”的函数“connectMember()”中,我有:

   [...]
if($isMember){
   [...]
}else{
   return $this->_app['twig']->render(
      'message.twig', 
      array('msg' => "This member does not exist.", 'class' => 'Warning'));
}
   [...]

但是 render() 方法不起作用。我要显示的错误消息没有显示,而是启动了“$ app-> redirect (...)”。

如何让我的班级使用当前对象 Silex\Application ?是否有更好的方法将自定义类绑定到 Silex 应用程序的实例?

非常感谢您的回答!


版本:添加信息

如果我使用:

return $connexion->connectMember();

显示错误消息。但这不是一个好的解决方案。 'connection' 类调用也使用此代码的其他类:

$this->_app['twig']->render(...). 

如何使 $ this->_app(存在于我的类中)对应于我的控制器中创建的变量 $app?

【问题讨论】:

  • 你试过return $connexion->connectMember();吗?现在 twig 正在渲染您的视图,但它从未在您的控制器中使用...
  • 我只是尝试,实际上是问题所在。如果我这样做:return $ connection-> connectMember (); 显示我的错误消息。但是我在其他路上还有更多的函数调用,例如:$ connection-> checkAccess (); $ member-> update ([...]);每个调用都包含错误返回,我做不到return $ connection-> checkAccess (); return $ member-> update ([...]); return $ app-> redirect ([...]);我需要考虑我的问题,但是谢谢你,你已经部分解决了我的问题。

标签: php object symfony twig silex


【解决方案1】:

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');

silexpimple的文档中了解更多信息(pimple是silex使用的容器)。

【讨论】:

  • 当我看到您的消息时,我正在阅读 Pimple 文档。我对服务的概念感到不舒服。谢谢你的回答,它解决了我的问题。
【解决方案2】:

如果你使用 $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['mycontroller']时会自动设置$app!

PS : 如果你不想使用 ->share() 尝试使用 __invoke($app) 因为 \Pimple::offsetGet() 调用它:p

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 2012-10-28
    • 2019-03-05
    相关资源
    最近更新 更多