Cakephp PHP WEB開発

【Cakephp2→4】addSubCommandは Cake3.6 で非推奨

※本サイトはPR表記を含みます。

Cake2 から Cake4 へのシェルの移行は、基本的にコマンドとして移行することになります。
そこで Cake2 の Shell 内に addSubCommand() が利用されている場合、コマンドでは利用できなくなっているため注意が必要です。

Cake2: addSubcommandを利用した例

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
class HogeShell extends AppShell {
public $uses = array('Hoge');
public function getOptionParser() {
$parser = parent::getOptionParser();
$parser->addSubcommand('fuga', [
'help' => 'fugaします',
'parser' => [
'options' => ['test' => [
'short' => 't',
'help' => 'テスト表示します',
]],
],
]);
}
public function fuga() {
print_r($this->Hoge->fugas());
}
}
<?php class HogeShell extends AppShell { public $uses = array('Hoge'); public function getOptionParser() { $parser = parent::getOptionParser(); $parser->addSubcommand('fuga', [ 'help' => 'fugaします', 'parser' => [ 'options' => ['test' => [ 'short' => 't', 'help' => 'テスト表示します', ]], ], ]); } public function fuga() { print_r($this->Hoge->fugas()); } }
<?php
class HogeShell extends AppShell {
    public $uses = array('Hoge');

    public function getOptionParser() {
        $parser = parent::getOptionParser();
        $parser->addSubcommand('fuga', [
            'help' => 'fugaします',
            'parser' => [
                'options' => ['test' => [
                    'short' => 't',
                    'help' => 'テスト表示します',
                ]],
            ],
        ]);
    }

    public function fuga() {
        print_r($this->Hoge->fugas());
    }
}

簡単な例として、コマンド fuga を定義し、モデル Hoge の fugas() をコールする形です。
もちろん、Hoge モデルには fugas() というメソッドが定義されていなければエラーとなりますが、そこは話題に触れない部分で「メソッドがある」と仮定し、コードは割愛します。

Cake2のシェルでは addSubcommand() を用意することで、簡単にサブコマンドを作成できていました。

次は Cake2 で定義した Shell を Cake4 に移行してみます。

Cake4: HogeFugaCommandを定義

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
declare(strict_types=1);
namespace App\Command;
use Cake\Console\Arguments;
use Cake\Console\Command;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\ORM\TableRegistry;
class HogeFugaCommand extends Command
{
/**
* インスタンス初期化
*
* @return void
*/
public function initialize(): void
{
parent::initialize();
$this->Hoges = TableRegistry::getTableLocator()->get('Hoges');
}
/**
* オプションパーサー
*
* フックメソッドで引数やオプションを定義する
*
* @param \Cake\Console\ConsoleOptionParser $parser 引数やオプションを定義
* @return \Cake\Console\ConsoleOptionParser コマンド定義されたオブジェクト
*/
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
$parser = parent::buildOptionParser($parser);
$parser->addOption('test', [
'short' => 't',
'help' => 'テスト表示します',
]);
return $parser;
}
/**
* コマンドが呼び出された時に実行
*
* @param \Cake\Console\Arguments $args コマンド引数
* @param \Cake\Console\ConsoleIo $io 対話形式で出力したりファイル作成などを提供
* @return void
*/
public function execute(Arguments $args, ConsoleIo $io): void
{
print_r($this->Hoges->fugas());
}
}
<?php declare(strict_types=1); namespace App\Command; use Cake\Console\Arguments; use Cake\Console\Command; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\ORM\TableRegistry; class HogeFugaCommand extends Command { /** * インスタンス初期化 * * @return void */ public function initialize(): void { parent::initialize(); $this->Hoges = TableRegistry::getTableLocator()->get('Hoges'); } /** * オプションパーサー * * フックメソッドで引数やオプションを定義する * * @param \Cake\Console\ConsoleOptionParser $parser 引数やオプションを定義 * @return \Cake\Console\ConsoleOptionParser コマンド定義されたオブジェクト */ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser = parent::buildOptionParser($parser); $parser->addOption('test', [ 'short' => 't', 'help' => 'テスト表示します', ]); return $parser; } /** * コマンドが呼び出された時に実行 * * @param \Cake\Console\Arguments $args コマンド引数 * @param \Cake\Console\ConsoleIo $io 対話形式で出力したりファイル作成などを提供 * @return void */ public function execute(Arguments $args, ConsoleIo $io): void { print_r($this->Hoges->fugas()); } }
<?php
declare(strict_types=1);

namespace App\Command;

use Cake\Console\Arguments;
use Cake\Console\Command;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\ORM\TableRegistry;

class HogeFugaCommand extends Command
{
    /**
     * インスタンス初期化
     *
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();

        $this->Hoges = TableRegistry::getTableLocator()->get('Hoges');
    }

    /**
     * オプションパーサー
     *
     * フックメソッドで引数やオプションを定義する
     *
     * @param \Cake\Console\ConsoleOptionParser $parser 引数やオプションを定義
     * @return \Cake\Console\ConsoleOptionParser コマンド定義されたオブジェクト
     */
    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        $parser = parent::buildOptionParser($parser);
        $parser->addOption('test', [
            'short' => 't',
            'help' => 'テスト表示します',
        ]);

        return $parser;
    }

    /**
     * コマンドが呼び出された時に実行
     *
     * @param \Cake\Console\Arguments $args コマンド引数
     * @param \Cake\Console\ConsoleIo $io 対話形式で出力したりファイル作成などを提供
     * @return void
     */
    public function execute(Arguments $args, ConsoleIo $io): void
    {
         print_r($this->Hoges->fugas());
    }
}

別にコマンド名はなんでもよいのかもですが、Cake2 からの移行の場合、複数のサブコマンドが存在すると想定すると「親コマンド名 + サブコマンド」のコマンド名がわかりやすいと思います。で、定義したコマンドを Cake2 と同様にサブコマンドとして稼働するように Application.php で定義する必要があります。

Cake4: Application.phpにサブコマンドを登録する

src/Application.php

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use App\Command\HogeFugaCommand;
use Cake\Console\CommandCollection;
// Applicationクラス内
// 以下のconsoleメソッドを追記し、コマンドの別名登録をして、サブコマンドの様に見せる
/**
* コマンドの登録・別名登録
*
* @param \Cake\Console\CommandCollection $commands コマンドコレクション
* @return \Cake\Console\CommandCollection 設定済みコマンドコレクション
*/
public function console(CommandCollection $commands): CommandCollection
{
// 使用可能なコマンドを検出して登録
$commands->addMany($commands->autoDiscover());
// コマンドの別名登録
$commands->add('Hoge fuga', HogeFugaCommand::class);
return $commands;
}
use App\Command\HogeFugaCommand; use Cake\Console\CommandCollection; // Applicationクラス内 // 以下のconsoleメソッドを追記し、コマンドの別名登録をして、サブコマンドの様に見せる /** * コマンドの登録・別名登録 * * @param \Cake\Console\CommandCollection $commands コマンドコレクション * @return \Cake\Console\CommandCollection 設定済みコマンドコレクション */ public function console(CommandCollection $commands): CommandCollection { // 使用可能なコマンドを検出して登録 $commands->addMany($commands->autoDiscover()); // コマンドの別名登録 $commands->add('Hoge fuga', HogeFugaCommand::class); return $commands; }
use App\Command\HogeFugaCommand;
use Cake\Console\CommandCollection;

// Applicationクラス内
// 以下のconsoleメソッドを追記し、コマンドの別名登録をして、サブコマンドの様に見せる
/**
* コマンドの登録・別名登録
*
* @param \Cake\Console\CommandCollection $commands コマンドコレクション
* @return \Cake\Console\CommandCollection 設定済みコマンドコレクション
*/
public function console(CommandCollection $commands): CommandCollection
{
    // 使用可能なコマンドを検出して登録
    $commands->addMany($commands->autoDiscover());

    // コマンドの別名登録
    $commands->add('Hoge fuga', HogeFugaCommand::class);

    return $commands;
}

上記コードのようにコマンドの別名登録をすることで、./bin/cake Hoge fuga というコマンドを実行することが可能になります。

注意したい点は、上記コード内の autoDiscover()addMany() しておかないと、既存のコマンドが検出されず、利用できない状態になってしまうことです。

crontabとかで稼働してるコマンド数が多かったらコワ...)

Cake4: サブコマンドの追加
https://book.cakephp.org/4/ja/console-commands/option-parsers.html#id14

Cake4: コマンド名を変更(ネストされたコマンド)
https://book.cakephp.org/4/ja/console-commands.html#renaming-commands

-Cakephp, PHP, WEB開発
-

S