株式会社ラクス  ITエンジニア総合支援サイト スタックアスタリスク フルマネージド専用サーバー エクスユニット
ITエンジニアとして 知る 学ぶ
 
Java
.NET
PHP
プログラミング一般
DataBase
システム/サーバ構築
システム/サーバ運用
技術系一般知識
 
 
>IT技術情報>php>PHP第2回:PHP中級
【連載 】PHP

第2回:PHP中級

 
【 ページ 】 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |


<<前のページへ

2外部プログラム実行

  ファイルの読み書き、排他制御、パイプの取り扱い、画像ファイルの取り扱いについて書きます。ファイルに対するその他の操作(パーミッションの設定、ファイル削除、日付の取得など)については、関数リファレンスの方をご覧ください。

また当然のことですが、ファイルを扱う際には、ファイルにしかるべきパーミッションが設定されている必要があります。



■system, exec,

  passthru外部プログラムを実行する際には、3 つの関数が用意されています(前章で出てきたパイプは省いています)。それぞれの違いは、返り値です。system 関数は、プログラムの実行結果を「文字列」として返します。exec は、プログラムの実行結果の最後の一行を同じく文字列としてかえします。passthru は、プログラムの実行結果をそのままのバイナリデータとして返します。

  つまり、実行結果が必要でない場合は exec、テキストを出力するプログラムの実行結果がすべて必要な場合は system、バイナリを出力するプログラムの実行結果が必要な場合はpassthru をというように使い分けます。

  また、backtick 演算子という機構も用意されています。ほぼ system と等価な機構です。(system ではプログラムの終了ステータスを取得することができますが、backtick 演算子ではそれができません。)バッククオート(`)で囲まれた内容をシェルに渡して実行し、出力を返します。

backtick 演算子使用例
 
1: $str = `/bin/ls -l /tmp`;


という形で、ls の結果が $str に格納されます。
 



■注意点

  system などの外部プログラム関数を使うスクリプトを作る際に注意しなければならない点があります。例えば、フォームから受け取った値の一部が system などに外部プログラムの引数の一部として渡すような場合、簡単に任意のコマンド(rm や cat /etc/passwd などの危険なコマンドでさえ)を発行できてしまいます。

たとえば、$fFilename という変数はフォームから渡される値であるとして、
 
1: $str = system("/bin/ls /tmp/$fFilename");

 
というようなスクリプトが実行される場合、$fFilename に、「; /bin/rm -rf /」と書けば、シェルに対して、「/bin/ls /tmp/; /bin/rm -rf /」というコマンドが渡されます。「;」 は、コマンドの区切りとして認識されますので、ls も rm も実行されてしまいます。

  このような問題を防ぐために、escapeshellcmd という関数が用意されています。「;」を含む、シェルに対して特別な意味を持つ文字をエスケープして出力します。

この関数を用いて、
 
1: $fFilename = escapeshellcmd($fFilename);
2: $str = system("/bin/ls /tmp/$fFilename");

 
としてやれば、先ほどのプログラムは(多少)安全になります。
 



■時間のかかるプログラムをバックグラウンドで動かしたい時は

  時間のかかる処理(大量のメール配信や、データベースの全件削除など)をブラウザから行いたいことがあります。そのような場合に、通常の方法で処理するとその時間がかかる処理が終了するまでユーザーがブラウザを使用できなくなります(IE の地球マークが廻りつづけている状態)。この間にユーザーがブラウザに対して操作を行った場合の動作は保証されません。また、ある一定の時間を超えると接続タイムアウトとなってしまうこともあります。

  本節ではこのような状態を避けるべく、ブラウザをすぐに開放し、時間のかかる処理はバックグラウンド処理(メイン処理の裏で動く状態)させるための方法を説明します。

  Perl などであれば、fork 関数を使い、同じプログラム中にバックグラウンドで処理させる部分を書くことができるのですが、PHP の場合には fork 関数がありませんので、バックグラウンド処理させる部分をあらかじめ別プログラムとしてつくっておき、system 関数や exec 関数で呼び出すという形になります。当然ですが、バックグラウンドで行われた処理の結果を得ることは不可能です。(メインの処理はバックグラウンドの処理の前にすでに終了しているので。)ですから、exec をつかうのも、system を使うのも同じです。

  system 関数や、exec 関数の関数リファレンスを見ると、次のような記述があります。


▼Java や Linux を体系的に学びましょう!▼
Stack*のラクスが、
新学習方式のカリキュラムを開発しました!
14700円から(*1)、Java や Linux を体系的に学べます!!
(*1 テキスト代のみの税込料金です)




  「この関数を使用してプログラム実行を開始し、バックグラウンドで実行したままにしたい場合には、プログラムの出力をファイルまたは他の出力ストリームにリダイレクトする必要があることにも注意して下さい。さもないと、PHPはそのプログラムの実行が終了するまでハングします。 」

  この文章の意味は、下記のプログラムのように記述しなさいという意味です。
 
system("/home/your/bgprog $arg1 $arg2 > /dev/null &");

 
  ここで、bgprog は、バックグラウンドで走らせたいプログラムです。どんな言語で書いてもかまいません。また、上記例のようにメインの処理から引数を渡したい場合には、bgprog 側できちんと受け取るようにしておかなければなりません。

  「> /dev/null」 が「リダイレクト」に相当する記述です。/dev/null というのは、「ゴミ箱」と思って頂いて構いません。すべての出力を捨てます。最後の & は、バックグラウンドで実行するという意味です。このあたりの詳しいことは UNIX のシェルの本をみれば載っています。「PHPはそのプログラムの実行が終了するまでハングします」というのは、つまり IE の地球マークが廻りつづける状態をいいます。

  実験をしてみます。ブラウザの挙動に注目してください。bgprog に相当するプログラムを下記内容でつくります。単に 10 秒間眠るプログラムです。ここではシェルスクリプトとしてつくります。

sleep.sh
 
sleep 10

 
つぎに、上記プログラムを呼び出す PHP スクリプトを作ります。
 
<?
  system("/bin/sh /home/your/sleep.sh > /dev/null &");
  echo "OK.";
?>

 
  上記ページを表示すると、瞬間的に OK が表示されたと思います。10 秒以内に ps コマンドで確認すると、 OK が表示された後も sleep.sh が走っています。

では、下記のように通常の呼び出し方に変更するとどうでしょうか?
 
<?
  system("/bin/sh /home/your/sleep.sh &");
  echo "OK.";
?>

 
  10 秒してから OK が表示されるとおもいます。その間、ブラウザは読み込み中となっていたこととおもいます。

おわかりいただけましたか?


>>次のページへ


【 目次 】
1.ファイル、パイプ
2.外部プログラム実行
3.正規表現・文字列
4.エンコード/デコード
5.マルチバイト
6.FORMからの値の受け取り
7.ファイルのアップロード

【 関連記事 】
PHP
第1回:PHP基礎
第2回:PHP中級
第3回:PHP応用

サイト内全文検索
スタックアスタリスクのサイトを検索します。検索には、Googleを利用しています。そのため、最新の情報で検索されない可能性があります。


簡単レンタルメールフォーム
300メガ1000円〜 XBitのレンタルサーバー
500メガ1995円〜 電話サポート/PostgreSQL/専用SSLなどにも対応!お客様のニーズを網羅したレンタルサーバ
ホームページ制作のアシストウェブ
STACK* 執筆の講師陣から習得する!! ITエンジニアスクール アイティブースト
統合メールサポートシステム 〜MailDealer(メールディーラー)〜
システム開発,IT教育 〜株式会社アイティーブースト(ITBoost)〜
簡単 営業支援/顧客管理ツール Easy Sales
  利用規約 お問い合わせ・ご意見 スタックアスタリスクについて 運営会社について 
  レンタルサーバー ホスティング 専用サーバー メールフォーム ショッピングカート メール共有 ITエンジニア派遣 Linux講座 Java講座 メール配信 レンタルサーバー Webデータベース 検索サービス
CopyrightcRAKUS Co.,Ltd. All Rights Reserved.  メール管理・共有 顧客管理(CRM)もできるメール対応サポートシステム JAVA LINUX CISCO 技術者派遣 育成事業 株式会社ラクス