如何创建ZF3控制台应用程序

18

在Zend Framework 2中,将初始模块横幅添加到控制台应用程序非常简单。我们只需要实现getConsoleBannergetConsoleUsage方法,并实现Zend\ModuleManager\Feature\ConsoleUsageProviderInterfaceConsoleBannerProviderInterface接口即可。这足以在通过CLI启动public/index.php时在控制台中转储这些消息。

但在Zend Framework 3中情况并不相同。进行相同的设置并不能提供相同的结果。实际上,在控制台中,我们看到骨架应用程序的默认HTML页面与我们通过浏览器访问该页面的方式相同。在安装自定义模块之前,我们就已经看到了那个页面。此处是zend-mvc-console模块的文件:https://zendframework.github.io/zend-mvc-console/intro/

即使按照建议安装了模块(在模块定义中添加了'Zend\Mvc\Console'),控制台横幅也不会显示。我在方法内测试过变量转储,并能够查看数据,所以框架执行了这些方法,但在控制台中没有显示任何结果。

我也尝试了使用控制台路由和控制器。路由被找到了,控制器操作也被执行了,但是在CLI中仍然什么都没有显示。

我查看了框架的代码,似乎Zend\Mvc\Console\ResponseSender\ConsoleResponseSender类从未执行过。我需要注册一些view_manager策略才能在CLI中得到显示吗? 这里有zf3骨架应用程序的源文件:https://gist.github.com/kachar/06f0c9096bcc1cc0b00f4612aed1b68b

运行该应用程序:

$ php -v
PHP 7.0.6 (cli) (built: Apr 27 2016 14:00:40) ( ZTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

$ php public/index.php
Application\Module::getConsoleBanner
Application\Module::getConsoleUsage

$ php public/index.php user
Application\Controller\IndexController::indexAction

1
可能是zend-mvc-console中的一个bug: https://github.com/zendframework/zend-mvc-console/issues/12 - avy
@kachar:你是否成功地按照@weierophinney的建议实现了zf-console?如果是,能否与我们分享一下如何实现的? - l_r
2个回答

13
根据我们的文档,MVC <-> Console 集成已被弃用。我们建议使用zf-consolesymfony console来构建应用程序的控制台功能。
我们知道zend-mvc-console存在问题,并将很快发布补丁版本来解决这些问题,从而解决您的短期问题。然而,我们建议长期迁移到其他解决方案。

Zend-MVC-Console被弃用的原因是什么? - wpsd
我尝试了zf-console,它很简单但是很难集成。我无法使用工厂创建处理程序,这意味着我必须注入整个服务管理器。我认为zf-console更专注于简单的单个应用程序,但如果我们想合并多个控制台,我认为这不是一个好的解决方案,会变得非常复杂。 - wpsd
2
如果您需要比zf-console提供的更多功能,symfony/console是一个很好的解决方案。事实上,我们正在使用symfony/console重写现有的工具或创建新的工具。至于为什么zend-mvc-console被弃用:这是因为zend-mvc和控制台工具根本不匹配,并且将它们集成会增加太多复杂性和边缘情况,使我们感到难以维护。 - weierophinney
是的,经过进一步研究,我已经迁移到了zf-console,但不确定zend事件(而不是mvc事件)是否可以在服务内工作。 - wpsd
当然,zend-eventmanager工作正常;它可以在任何PHP应用程序中独立使用。 - weierophinney

1

对于那些决定同时使用zend framework 3(或laminas)和symfony/console的人(正如@weierophinney所提到的),我建议使用来自zend framework官方论坛的这个答案https://discourse.laminas.dev/t/how-to-launch-a-basic-php-cli/1473/11(作者rieschl)。我将从那里复制代码:

我编写了不同的“单文件”脚本,但最终发现如果你的cli脚本需要进化,那么symfony/console是最好的选择。而且设置非常容易。我所做的就是让ServiceManager创建Symfony控制台应用程序,因此我的CLI入口点(bin/console)如下:

#!/usr/bin/env php
<?php

declare(strict_types=1);

use Laminas\Mvc\Application as ZfApp;
use Symfony\Component\Console\Application as ConsoleApp;

chdir(dirname(__DIR__));

require dirname(__DIR__) . '/vendor/autoload.php';

$zfApp = ZfApp::init(require dirname(__DIR__) . '/config/application.config.php');
/** @var ConsoleApp $consoleApp */
$consoleApp = $zfApp->getServiceManager()->get(ConsoleApp::class);
return $consoleApp->run();

正如您所看到的,我构建了Laminas应用程序(这里称为ZfApp,它是Laminas之前的版本),从中获取了ServiceManager和Symfony控制台。服务工厂如下所示。
<?php

declare(strict_types=1);

namespace Eventjet\Factory;

use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;

final class ConsoleApplicationFactory
{
    public function __invoke(ContainerInterface $container): Application
    {
        $app = new Application(
            'Eventjet Console Legacy System',
            '1.0'
        );
        foreach ($this->createCommands($container) as $command) {
            $app->add($command);
        }
        return $app;
    }

    /**
     * @return Command[]
     */
    private function createCommands(ContainerInterface $container): array
    {
        $commandNames = $this->config($container)['ej-console']['commands'];
        return array_map(
            static function (string $commandName) use ($container) {
                return $container->get($commandName);
            },
            $commandNames
        );
    }

    /**
     * @return mixed[]
     */
    private function config(ContainerInterface $container): array
    {
        return $container->get('config');
    }
}

那样的话,我只需要创建一个新的控制台类,在配置文件中将其注册为类字符串,并在 [‘ej-console’][‘commands’] 配置键下立即使用它 :slight_smile: 配置文件应该如下所示:
return [
    'ej-console' => [
        'commands' => [
            SomeCommand::class,
        ],
    ],
];

那个答案帮助我在一天内开始使用zf3和symfony/console


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接