LoginSignup
2
0

More than 5 years have passed since last update.

独自オプションを作成してShellを実装してみた

Last updated at Posted at 2019-03-05

環境

  • PHP 7.2.6
  • CakePHP 3.6.13

やりたい事

  • DBの値更新
    • オプション無しの場合
      • 対象カラムの値全更新
    • オプション有りの場合
      • 対象カラムの指定箇所のみ更新

Shellクラス作成

  • CakePHPのbakeコマンドでShellクラス作成
$ bin/cake bake shell sample


Creating file /vagrant/yourmystar.jp/src/Shell/SampleShell.php
Wrote `/vagrant/yourmystar.jp/src/Shell/SampleShell.php`

Baking test case for App\Shell\SampleShell ...

Creating file /vagrant/yourmystar.jp/tests/TestCase/Shell/SampleShellTest.php
Wrote `/vagrant/yourmystar.jp/tests/TestCase/Shell/SampleShellTest.php` 
  • 下記のようなShellが作成される

スクリーンショット 2019-03-05 16.18.43.png

  • getOptionParser

  • main

    • 実行処理を定義

実装

<?php
namespace App\Shell;

use Cake\Console\Shell;

/**
 * Sample shell command.
 */
class SampleShell extends Shell
{

    /**
     * Manage the available sub-commands along with their arguments and help
     *
     * @see http://book.cakephp.org/3.0/en/console-and-shells.html#configuring-options-and-generating-help
     *
     * @return \Cake\Console\ConsoleOptionParser
     */
    public function getOptionParser()
    {
        $parser = parent::getOptionParser();

        $parser->addOption('target_id', [
            'help' => '更新対象のIDを指定する'
        ]);

        return $parser;
    }

    public function initialize()
    {
        parent::initialize();
        $this->loadModel('Hoge');
    }

    /**
     * main() method.
     *
     * @return bool|int|null Success or error code.
     */
    public function main()
    {
        $offset = 0;
        $executionDate = date('Y-m-d H:i:s');

        $this->out($executionDate . " [Start]");

        while (true) {
            $samples = $this->Hoge
                ->find()
                ->offset($offset)
                ->limit(100);

            if (isset($this->params['target_id'])) {
                $samples->where(['id IN' => explode(',', $this->params['target_id'])]);
            }

            $samples = $samples->toArray();

            if (empty($samples)) {
                break;
            }

            foreach ($samples as $sample) {
                $sample->flg = 1;
                $this->Hoge->save($sample);
                $this->out('Update Id:' . $sample->id);
            }

            $offset += 100;
        }

        $this->out($executionDate . " [End]");
    }
}

解説

  • getOptionParser
  • DBからデータ取得
    • HogeTableからデータを100件ずつ取得
    • オプションが指定された場合、where句に指定される
      • explodeでIDの複数指定を可能にしている
  • カラムの値更新
    • flgカラムの値を1に更新
  • offsetの値追加
    • 100件ずつ取得するので、次の100を取得するために$offset += 100;をする

変数名は基本「仮」なのでご了承下さい。

実行結果

  • 通常実行
$ bin/cake sample
2019-03-05 20:37:52 [Start]
Update Id:1
Update Id:2
・
・
・
2019-03-05 20:37:52 [End]
  • オプション指定実行
$ bin/cake sample --target_id=1
2019-03-05 20:39:51 [Start]
Update Id:1
2019-03-05 20:39:51 [End]
  • オプション複数指定実行
$ bin/cake sample --target_id=1,2,3
2019-03-05 20:39:51 [Start]
Update Id:1
Update Id:2
Update Id:3
2019-03-05 20:39:51 [End]
  • help表示
$ bin/cake sample --help
Usage:
cake sample [-h] [-q] [--target_id] [-v]

Options:

--help, -h       Display this help.
--quiet, -q      Enable quiet output.
--target_id      更新対象のIDを指定する // addOptionメソッドで追加したオプション
--verbose, -v    Enable verbose output.

簡単!!!

おまけ

Twitterやってます!外部のエンジニアの方ともどんどん繋がりたいと考えていますので、是非フォローして頂ければと思います!@Tatsuo96
ブログ始めました!
https://note.mu/tatsuo_iriyama

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0