<< 初フルマラソン完走(?) 〜第11回荒川市民マラソン〜 | main | 携帯での動画・着うた配信 〜ストリーミング or ダウンロード〜 >>

PHP で外部コマンド実行 〜popen 開けパイプ〜

「PHP で外部コマンド実行」で真っ先に思い浮かぶのは以下の関数達。

・exec
・system
・passthru
・shell_exec
・バッククォート演算子(``)

それぞれの関数に違いはありますが, “コマンドの実行”という意味ではどれも似たようなもの。

PHP でメールを送信をするにあたり, mail関数が使えず SMTP経由でのメール送信は面倒。
ちょうど qmail が入っていたので qmail-inject でメール送信する簡単な関数を作ることにしました。

$mailData = "From: ${from}\r\n";
$mailData .= "To: ${to}\r\n";
$mailData .= "Subject: " . mb_encode_mimeheader($subject) . "\r\n";
$mailData .= "Mime-Version: 1.0\r\n";
$mailData .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\r\n";
$mailData .= "Content-Transfer-Encoding: 7bit\r\n";
$mailData .= mb_convert_encoding($body, 'ISO-2022-JP');

こんな感じで PHP でメールデータを作成して外部コマンド経由で送信しようとしたわけです。

system("echo \"${mailData}\" | /path/to/qmail-inject");
期待通りメールは送信できたものの, 日本語の時に本文がちょん切れてしまう現象が発生。
JIS のエスケープシーケンスが悪さして本文がおかしくなっているんだろうか...

$mailData をいったんファイルに落として,

system("cat /tmp/maildata | /path/to/qmail-inject");

とすればうまくいきそうだけど, 一時ファイル作って消すなんて面倒なこともやりたくない。

プロセスへのパイプを fopen で開けないものか, と調べてみると...ありました, まさにそのものの関数が。

popen - プロセスへのファイルポインタをオープンする

そういえば popen 使って同じようなことやってるプログラムを遥か昔に見たような気がします。

というわけで popen で万事解決。

$pp = popen('/path/to/qmail-inject', 'w');
fwrite($pp, $mailData);
pclose($pp);

popen でパイプ入出力ができるのって結構便利。

入出力の両方のポインタを開く proc_open って関数もあるようです。
はてブへ追加 この記事のはてブユーザ
PHP | comments (0) | - | pagetop↑

Comments

Post your Comment