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’
スクリプトに渡されたコマンドライン引数の数 (コマンドラインから実行した場合) です。
気がつけば最初からそうすればよかったという内容ですが...しばらく気が付きませんでした。
来年もよいCodeIgniterライフをどうぞ。