cakephp 4 consoleoptionparser用法

发布于 2025-01-23 05:50:13 字数 3442 浏览 4 评论 0 原文

在我的CakePHP 4.0项目中,我正在努力实现我认为是一个相当微不足道的目标:我希望拥有一个“基础”控制台命令,并具有一些基本的设置以及其他扩展其的类。

具体来说,我想在我的基类中定义一个[ consoleoptionparser ] [1],因为所有其他命令类都应访问相同的选项:

<?php

namespace Import\Shell;

use Cake\Command\Command;
use Cake\Console\ConsoleOptionParser;

class BaseImportCommand extends Command
{
    public function __construct()
    {
        parent::__construct();

        // setup some stuff related to my project here
    }

    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        // Get an empty parser from the framework.
        $parser = parent::getOptionParser();

        // Define your options and arguments.
        $parser->addOptions(
            [
                'country' => [
                    'short' => 'c',
                    'help' => 'The country for which to execute the operation.',
                    'required' => false,
                ],
                'author' => [
                    'short' => 'a',
                    'help' => 'The ID of the author for which to execute the operation.',
                    'required' => false,
                ],
                'product' => [
                    'short' => 'p',
                    'help' => 'The ID of the product for which to execute the operation.',
                    'required' => false,
                ],
            ]
        );

        // Return the completed parser
        return $parser;
    }
}

<?php

namespace Import\Shell;

use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;

class ProcessProductImagesCommand extends BaseImportCommand
{
    public function __construct()
    {
        parent::__construct();

        // setup some more stuff here
    }

    /**
     * execute() method.
     *
     * @return bool|int|null Success or error code.
     */
    public function execute(Arguments $args, ConsoleIo $io)
    {
        $country = $args->getOption('country');
        $productId = $args->getOption('product');

        // do my logic here
    }
}

问题是,当我

bin/cake processProductImages -c CH

在Shell I中 运行时,得到这个错误:

Error: Unknown short option `c`.

为什么?我没有重新定义 buildoptionparser 方法 processProductimagesCommand 类,因此我假设 consoleoptionparser 配置是从 basecommand basecommand /代码>类。

为了解决该问题,我尝试将此方法添加到 ProcessProductimagesCommand 类:

    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        return parent::buildOptionParser($parser);
    }

但是在这种情况下,当我

bin/cake processProductImages -c CH

在shell中运行时会发生什么,然后才会遇到此错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /var/www/repo/public/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php on line 430

我找到了唯一的实际方法要拥有我需要的选择,在我需要的课堂中,通过复制整个 consoleoptionparser 在子类中重复的初始化,从 baseImportCommand 类,但显然我不喜欢此解决方案,因为它会导致无用的代码重复。 [1]: https://book.cake.cakephp.org/ 4/en/console-commands/option-parsers.html

In my CakePHP 4.0 project, and I'm trying to achieve what I think is a fairly trivial goal: I would like to have to have a "base" console command, with some basic setup, and other classes that extend it.

Specifically, I would like to define a [ConsoleOptionParser][1] in my base class, because all other Command classes should have access to the same options:

<?php

namespace Import\Shell;

use Cake\Command\Command;
use Cake\Console\ConsoleOptionParser;

class BaseImportCommand extends Command
{
    public function __construct()
    {
        parent::__construct();

        // setup some stuff related to my project here
    }

    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        // Get an empty parser from the framework.
        $parser = parent::getOptionParser();

        // Define your options and arguments.
        $parser->addOptions(
            [
                'country' => [
                    'short' => 'c',
                    'help' => 'The country for which to execute the operation.',
                    'required' => false,
                ],
                'author' => [
                    'short' => 'a',
                    'help' => 'The ID of the author for which to execute the operation.',
                    'required' => false,
                ],
                'product' => [
                    'short' => 'p',
                    'help' => 'The ID of the product for which to execute the operation.',
                    'required' => false,
                ],
            ]
        );

        // Return the completed parser
        return $parser;
    }
}

<?php

namespace Import\Shell;

use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;

class ProcessProductImagesCommand extends BaseImportCommand
{
    public function __construct()
    {
        parent::__construct();

        // setup some more stuff here
    }

    /**
     * execute() method.
     *
     * @return bool|int|null Success or error code.
     */
    public function execute(Arguments $args, ConsoleIo $io)
    {
        $country = $args->getOption('country');
        $productId = $args->getOption('product');

        // do my logic here
    }
}

The problem is that when I run

bin/cake processProductImages -c CH

in the shell I get this error:

Error: Unknown short option `c`.

Why is that? I am not redefining the buildOptionParser method inside the ProcessProductImagesCommand class, so I would assume that the ConsoleOptionParser configuration is inherited from the BaseCommand class.

To fix the problem, I have tried adding this method to the ProcessProductImagesCommand class:

    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        return parent::buildOptionParser($parser);
    }

but what happens in this case when I run

bin/cake processProductImages -c CH

in the shell I then get this error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /var/www/repo/public/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php on line 430

I have found out the the only actual way to have the options that I need, in the classes that I need them, is to completely repeat the initialisation of the ConsoleOptionParser in the child class by copying the whole buildOptionParser method from the BaseImportCommand class, but obviously I don't like this solution as it leads to useless code repetition.
[1]: https://book.cakephp.org/4/en/console-commands/option-parsers.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼泪淡了忧伤 2025-01-30 05:50:13
  • 通过惯例 命令< /strong> 应该生活在命令名称空间中,而不是 shell namespace。


  • 您无法调用 parent :: buildoptionparser()没有任何参数。

  • addargument()的第一个参数是 \ cake \ console \ consoleinputargument ,而不是数组。 > 可以使用 addarguments()方法一次添加

  • (位置值)和 选项 是两种不同的东西, -c 是需要使用 addoption()

    配置的选项。

  • 如果您在选项解析阶段耗尽了130多MB的内存,那么您可能会创建一个无限的循环。

  • By convention commands are supposed to live in the Command namespace, not the Shell namespace.

  • You cannot call parent::buildOptionParser() without any arguments.

  • The first argument of addArgument() is meant to be a string, or an instance of \Cake\Console\ConsoleInputArgument, not an array. Multiple arguments can be added at once using the addArguments() method (note the trailing s).

  • Arguments (positional values) and options are two different things, -c is an option that needs to be configured using addOption().

  • If you're exhausting 130+ MB of memory in the options parsing stage, then you possibly created an infinite loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文