CLIで実行されているPHPスクリプトにコマンドライン引数としてデータを渡すことができます。$argv
このデータは、配列内の子スクリプトで使用できます。
input.php:
$arg = "Data!";
exec("/usr/bin/php /path/to/data.php ".escapeshellarg($arg)." > /dev/null 2>&1 &");
data.php
$fp = fopen('data.txt', 'w');
fwrite($fp, $argv[1]);
fclose($fp);
いくつかのメモ:
- ユーザーがシェルにコマンドを挿入できないようにするために、各引数を渡すことが重要です。これにより、引数の特殊なシェル文字がスクリプトを壊さないようにすることもできます。
escapeshellarg()
$argv
はグローバル変数であり、やのようなスーパーグローバルではありません。グローバルスコープでのみ使用できます。関数スコープでアクセスする必要がある場合は、を使用できます。これは、私が許容できるものの使用を検討する唯一の状況ですが、起動時にグローバルスコープで引数を処理し、それらを引数としてスコープに渡す方がよいでしょう。$_GET
$_POST
$GLOBALS['argv']
$GLOBALS
$argv
は0インデックスの配列ですが、最初の「引数」はにあり$argv[1]
ます。実際にはPHPバイナリに渡される引数を表し、スクリプトへのパスが最初である$argv[0]
ため、常に現在実行中のスクリプトへのパスが含まれます。$argv
- コマンドライン引数の値は常に文字列型です。PHPはその型付けに非常に無差別であるため、スカラー値ではこれは問題ではありませんが、(かなり明らかに)コマンドラインからベクトル型(オブジェクト、配列、リソース)を渡すことはできません。
serialize()
たとえば、またはでエンコードすることにより、オブジェクトと配列を渡すことができますjson_encode()
。コマンドラインからリソースを渡す方法はありません。
編集ベクトルタイプを渡すときserialize()
は、オブジェクトが属するクラスに関する情報が含まれているため、使用することを好みます。
次に例を示します。
input.php:
$arg = array(
'I\'m',
'a',
'vector',
'type'
);
exec("/usr/bin/php /path/to/data.php ".escapeshellarg(serialize($arg))." > /dev/null 2>&1 &");
data.php
$arg = unserialize($argv[1]);
$fp = fopen('data.txt', 'w');
foreach ($arg as $val) {
fwrite($fp, "$val\n");
}
fclose($fp);
このプロセスを簡略化するために使用するクリップコレクションの関数を次に示します。
// In the parent script call this to start the child
// This function returns the PID of the forked process as an integer
function exec_php_async ($scriptPath, $args = array()) {
$cmd = "php ".escapeshellarg($scriptPath);
foreach ($args as $arg) {
$cmd .= ' '.escapeshellarg(serialize($arg));
}
$cmd .= ' > /dev/null 2>&1 & echo $$';
return (int) trim(exec($cmd));
}
// At the top of the child script call this function to parse the arguments
// Returns an array of parsed arguments converted to their correct types
function parse_serialized_argv ($argv) {
$temp = array($argv[0]);
for ($i = 1; isset($argv[$i]); $i++) {
$temp[$i] = unserialize($argv[$i]);
}
return $temp;
}
大量のデータ(getconf ARG_MAX
バイトの出力よりも大きい)を渡す必要がある場合は、シリアル化されたデータをファイルにダンプし、コマンドライン引数としてファイルへのパスを渡す必要があります。