CodeIgniter3 CLI利用時の引数の挙動

PHPのフレームワークの1つであるCodeIgniter3、今年はPHPでバッチ処理を作る際にCLI機能を利用しました。その時のTIPSです。時は過ぎた気がしますが空いていたので CodeIgniter Advent Calendar 2017 22日目記事に登録しました。

CodeIgniter CLI 機能

CLIとはcommand-line interfaceの略で、ターミナルからCodeIgniterの機能を呼び出します。

実装は簡単で、Controllerを書いて、index.php をConsoleから起動します。

<?php
defined( 'BASEPATH' ) OR exit('No direct script access allowed');

class Tools extends CI_Controller {

public function echoparam($param1='',$param2='')
{
echo "param1={$param1}".PHP_EOL;
echo "param2={$param2}".PHP_EOL;
}
}
$ php index.php tools echoparam apple orange
param1=apple
param2=orange

これでTools コントローラーのメソッド message が起動されます。
あとは動作させたい処理をCodeIgniterの機能を利用して記述できます。便利です。

引数の挙動の注意点

しかし、この引数には少しクセがあります。例えばURLを渡すと

$ php index.php tools echoparam https://google.com/
param1=https:
param2=google.com

引数に渡したURLが分割されてしまいました

どうしてこうなるのか

CodeIgniterはWebで利用されるときにURLでルーティング処理しています。

例えば、このURLを起動すると、productsコントローラーのshoesメソッドにsandals 123のパラメータが渡ります。

example.com/index.php/products/shoes/sandals/123<?php
class Products extends CI_Controller {

public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}

CLIで動く場合にもこの挙動のため、 URI中の/でパラメータを分割してしまいます。

CLIでURL引数を渡す方法

ではURLのような文字列を引数に指定するにはどうすればよいでしょうか。

  • 方法1 引数URLエンコードして渡す
$ php index.php tools echoparam https%3a%2f%2fgoogle%2ecom%2f
param1=https%3a%2f%2fgoogle%2ecom%2f
param2=

このように分割されずに値が渡ります。
あとはURLデコードして利用すれば良いです。しかし、いちいち引数をURLエンコードして指定するのは大変です。

・方法2 コントローラーで $_SERVER["argv"] を使う

class Tools extends CI_Controller {

public function echoparam()
{
$argv = $_SERVER["argv"];
$param1 =$argv[3];

echo "param1={$param1}".PHP_EOL;
}
$ php index.php tools echoparam https://google.com/
param1=https://google.com/

PHPの$_SERVER にはCLI実行時にはargc 、argvがセットされるのでそれを利用します。

$_SERVER["argv"]には次の情報が入っていて、$argv[3]以降に引数が入っています。

Array
(
[0] => index.php
[1] => tools
[2] => echoparam
[3] => https://google.com/
)

‘argv’

スクリプトに渡された引数の配列です。スクリプトがコマンドラインから 実行された場合、C 言語スタイルでコマンドライン引数に アクセスすることができます。GET メソッドを通してコールされた場合には 検索引数が格納されます。

‘argc’

スクリプトに渡されたコマンドライン引数の数 (コマンドラインから実行した場合) です。

PHP: $_SERVER — Manual

気がつけば最初からそうすればよかったという内容ですが...しばらく気が付きませんでした。

来年もよいCodeIgniterライフをどうぞ。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store