从Controller调用命令不起作用

时间:2017-07-29 13:20:12

标签: symfony

我有这个代码从控制器运行架构更新命令我从symfony document得到了帮助 我有这个代码:

namespace AdminBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class DefaultController extends Controller
{
    /**
     * @Route("/admin")
     */
    public function indexAction(KernelInterface $kernel)
    {
        $application = new Application($kernal);

        $input = new ArrayInput(array(
            'command' => 'doctrine:schema:update'
        ));

        $output = new NullOutput();
        $application->run($input, $output);

        return new Response("");
    }
}

这对我不起作用我在打开此网址(http://127.0.0.1:8000/admin)后收到此错误:

Controller "AdminBundle\Controller\DefaultController::indexAction()" requires that you provide a value for the "$kernel" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.

我该怎么办?

2 个答案:

答案 0 :(得分:4)

而不是将KernelInterface $kernel直接注入到您的操作中(我猜,您并未将其用作声明的服务),而是直接调用您的容器来询问内核:

public function indexAction()
{
    $kernel = $this->get('kernel');
    $application = new Application($kernel); // btw: you have an typo in here ($kernal vs $kernel)

    $input = new ArrayInput(array(
        'command' => 'doctrine:schema:update'
    ));

    $output = new NullOutput();
    $application->run($input, $output);

    // tip: use "204 No Content" to indicate "It's successful, and empty"
    return new Response("", 204);
}

答案 1 :(得分:2)

虽然Michael的回答有效,但它并不是Symfony 3.3中的首选方法,它对dependency injection进行了多处更改。通过对服务配置进行一些更改,您的代码实际上可以正常工作。

正如文档所述,Symfony 3.3中的依赖注入容器已更改,默认情况下为controllers are registered as services

# app/config/services.yml
services:
    # ...

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

这允许您通过控制器操作方法中的参数自动装配内核,就像您尝试过的那样。您的工作原因是因为您的AdminBundle可能未按照AppBundle默认设置app/config/services.yml的方式进行设置。要以Symfony 3.3想要的方式真正解决问题,您应该将AdminBundle添加到您的服务配置中,如下所示:

# app/config/services.yml
services:
    # add this below your AppBundle\Controller definition
    AdminBundle\Controller\:
        resource: '../../src/AdminBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

这样,您就不再需要致电$this->get('kernel');了,原始代码将按照您的方式运行,KernelInterface作为操作方法的参数。

此外,您可以扩展新的 AbstractController 而不是常规控制器,然后调用$this->get()将不再有效,这就是Symfony的方式。

再一次,虽然迈克尔的答案会很好,但我建议你实施我给出的答案,因为Symfony 3.3更倾向于采用这种方法。