How to create ZF3 console application
Asked Answered
A

2

18

In Zend Framework 2 it's very simple to add the initial module banner to the console applications.

All we need to is to implement the getConsoleBanner and getConsoleUsage methods and implement the Zend\ModuleManager\Feature\ConsoleUsageProviderInterface or ConsoleBannerProviderInterface interfaces.

This is good enough to dump those messages in the console when public/index.php is started via CLI.

In Zend Framework 3 it's not the same.

Doing the same setup does not provide the same result. Actually in the console we see the default html page for the skeleton app the same way as we visit it via the browser.

That page is being seen before we install the custom module: Here are the docs for the zend-mvc-console module https://zendframework.github.io/zend-mvc-console/intro/

Even after module is installed as suggested ('Zend\Mvc\Console' added in module definitions) the console banners are not shown. I've tested with var dumping inside the methods and I'm able to view the data, so the framework executes those methods but shows no result in the console.

I've tested with console routes and controllers. Route is found, controller action is executed but nothing is shown in the cli again.

I've digged in the code of the framework and it seems the Zend\Mvc\Console\ResponseSender\ConsoleResponseSender class is never executed.

Do I have to register some view_manager strategies in order to get something displayed in the CLI?

Here are the sources on top of the zf3 skeleton application: https://gist.github.com/kachar/06f0c9096bcc1cc0b00f4612aed1b68b

Running the app:

$ 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
Aranyaka answered 28/7, 2016 at 12:19 Comment(2)
It might be a bug in zend-mvc-console: github.com/zendframework/zend-mvc-console/issues/12Selfcentered
@kachar: did you succeed in implementing zf-console as suggested by @weierophinney? If you did, would you share how with us?Jeaninejeanlouis
P
13

Per our own documentation, MVC <-> Console integration is deprecated. We recommend using zf-console or symfony console for building console functionality for your application.

We are aware of issues with zend-mvc-console, and we'll be issuing a patch release soon to address them, which will fix your short-term problems. However, we recommend migrating to another solution in the long-term.

Purkey answered 29/8, 2016 at 13:51 Comment(5)
what is the reason zend-mvc-console is deprecated ?Carangid
I tried zf-console, it's simple but it's difficult to integrate. I cannot create handler using Factory, which mean I have to inject the whole service manager. I think zf-console is more focus on simple single app, but if we want to merge multiple console I don't think it's a good solution, it's very dirty.Carangid
If you need more features than zf-console offers, symfony/console is an excellent solution. We are, in fact, rewriting existing tooling or creating new tooling using symfony/console. As to why zend-mvc-console being deprecated: it's because zend-mvc and console tooling are simply a bad fit, and integrating them adds far too much complexity and edge cases for us to feel comfortable maintaining.Purkey
Yeah I migrate to zf-console after further study, but not sure whether zend event ( not mvc event ) can work inside service.Carangid
Yes, of course zend-eventmanager works fine; it can be used standalone in any PHP application.Purkey
I
1

For anyone who have decided to use zend framework 3 (or laminas) and symfony/console together (as @weierophinney mentioned) I recommend to use this answer from zend framework official forum https://discourse.laminas.dev/t/how-to-launch-a-basic-php-cli/1473/11 (author rieschl ). I will copy the code to here from there:

I’ve written different “single file” scripts, but in the end symfony/console is the best if your cli scripts evolve. And it’s amazingly easy to setup. What I’ve done is to let the ServiceManager create the Symfony console app, so my CLI entry point (at bin/console) looks like this:

#!/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();

As you can see, I build the Laminas App (called ZfApp here, it’s pre-Laminas), get the ServiceManager from there and the Symfony console from the ServiceManager. The Service Factory looks like this

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

That way, I can just create a new Console Class, register as class-string in the config under the [‘ej-console’][‘commands’] config key and have it availabe right away :slight_smile: The config would look something like that:

return [
    'ej-console' => [
        'commands' => [
            SomeCommand::class,
        ],
    ],
];

That answer help me to start using zf3 and symfony/console in one day.

Inoperable answered 3/2, 2021 at 14:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.