Cakephp PHP WEB開発

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

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

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

Cake2: addSubcommandを利用した例

<?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を定義

<?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

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開発
-