将CLI命令添加到Magento 2的正确,受支持的方法


9

是否存在将您的CLI命令添加到Magento 2模块的正确且受官方支持的方法?根据我的收集,您的选择是

  1. 将命令类添加到via 文件的commands参数中Magento\Framework\Console\CommandListdi.xml

  2. 通过\Magento\Framework\Console\CommandLocator::register一个registration.php或多个cli_commands.php文件注册命令

这些选项都不是带有祝福的@api。尚不清楚,作为扩展开发人员,我们应该如何添加命令行脚本,以使它们在版本之间保持一致。

有人知道在Right™方法上是否有正式的Magento政策吗?

Answers:


6

cli_commands.php如果将命令添加到非模块化程序包中,则应使用该命令。因此,如果命令在模块中并且可以(希望)仅在启用模块时可用,di.xml则应使用该命令。如果您不想添加模块,而只想拥有一个任意的Composer软件包,则可以cli_commands.php在此处注册命令。当然,它应该真正独立于Magento。或者,就目前而言,即使禁用了某个模块,也可以使用这种方法来注册必要的命令(确保它不依赖于仅在启用该模块时才起作用的任何模块逻辑)。


11

正确的方法是:

像创建任何类型的模块一样创建模块

只需创建您的registration.php文件

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'My_Module',
    __DIR__
);

并创建您的module.xml文件:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="My_Module" setup_version="0.1.0">
    </module>
</config>

在添加一个条目di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="my_command" xsi:type="object">My\Module\Command\Mycommand</item>
            </argument>
        </arguments>
    </type>
</config>

创建命令类:

<?php
namespace My\Module\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Mycommand extends Command
{
    protected function configure()
    {
        $this->setName('my:command');
        $this->setDescription('Run some task');

        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Hello world!');
    }
}

要运行任务,只需键入:

php bin/magento my:command

关于兼容性:

@api对于命令不是必需的,它用于服务合同 AFAIK。

如果需要让它们兼容,只需在脚本内使用接口API,而不是在其中添加逻辑即可。

例如:

<?php
use My\Module\Api\TaskInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MyCommand extends Command
{
    protected $taskInterface;

    public function __construct(
        TaskInterface $taskInterface
    ) {
        $this->taskInterface= $taskInterface;
        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('my:command');
        $this->setDescription('Run some task');

        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->taskInterface->runTask();

        $output->writeln('Done.');
    }
}

1
有用的信息+1,但是您确定吗?Magento样本数据模块使用cli_commands.php方法,这看起来更干净,而且如果Magento更改-alan Magento\Framework\Console\CommandList
Storm

我不是100%确信,只有Magento itslef可以回答这个问题,但是我已经玩了一段时间了,如果您删除“ cli_commands.php”,您仍然会在bin / magento中看到您的命令可用。他们还在di.xml上声明了它们,因此我认为它只是beta版本中仍然存在的东西。就像是针对建筑商和工厂一样。如果看到的话,cli_command.php仅用于示例数据。
Phoenix128_RiccardoT

是什么让您说@api将被弃用?
克里斯托夫在Fooman,2016年

@Kristof,对不起,我没有正确理解其中一位训练有素的合作伙伴解决方案幻灯片,因此请忽略该句子。我修改了我的帖子,将其删除。
Phoenix128_RiccardoT

3

如果我理解正确,那么在DI上的CommandList中定义的命令仅在已安装的Magento实例中可用,也仅适用于Magento模块(因为必须在di.xml中定义):https : //github.com/magento /magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124

上述方法中的Magento \ Framework \ App \ DeploymentConfig :: isAvailable()在Config中检查安装日期以检查已安装的Magento2:https : //github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/内部/ Magento /框架/App/DeploymentConfig.php#L83)。

另一方面,在Magento \ Framework \ Console \ CommandLocator中定义的命令始终可用,甚至可以由非Magento模块通过静态CommandLocator :: register方法在由作曲家自动加载的文件中定义(例如cli_commands.php)

https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L130

https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L146

因此,我认为这两种方法都是必需的,并且具有存在的权利


+1是一个很好的观察结果,但是为什么在未安装相关模块的情况下您需要Magento脚本?
Phoenix128_RiccardoT

1
关于未安装的magento实例beeing。在安装magento2之前,有几个命令可用。例如sampledata:deploy命令,如果您想直接使用magento2安装程序安装示例数据,这将很有意义。
David Verholen '16

我想你是对的。因此,当您需要在安装模块之前运行某些任务时,Magento模块的“正确”方法是使用di.xml(如我的回答)并使用“ cli_command.php”。确实有道理。
Phoenix128_RiccardoT

是的,我认为应该是这样。+1是因为我认为您有正确的答案(而且解释得很好),但这不适合置评;)
David Verholen

谢谢@David Verholen,我的+1是我给了您+1,而不是您应得的+1;)
Phoenix128_RiccardoT
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.