PHPを勉強中です。 あるサンプルプログラムの事でわからないことがあり、教えてください。

htmlファイルの入力フォ-ムに1つのテキストエリアがありまして、
<form action="./hoge.php" method="POST">によりそのテキストエリアの値(name=abc)がhoge.phpに渡されます。

hoge.phpには、
require( dirname( __FILE__ ) . '/config.php' );
~中略~
$abc = $_POST['abc'];
$command = $php_path . ' ' . $script_path . ' ' . $abc . ' >/dev/null 2>&1 &';
exec( $command );

となっており、値abcを$abcとして読み込んでいます。ここまではわかるのですが、別のファイル(bobubobu.php)にも$abcは登場するのです。

どうやって違うファイルであるbobubobu.phpにも$abcを読み込んでいるのでしょう。
includeやrequireの類は一切使っていないのです。ス-パ-グロ-バル変数とかでもないのです。
bobubobu.php内の臭そうな部分は、
$abc = $argv[1];
だけなのです(唐突に$abcが現れます)。
全くわからず困っております。
また、最初の入力フォ-ムにテキストフォ-ムがもう一つあったとして(name=efg)、このefgもhoge.phpを経由してbobubobu.phpに登場させることはできるのでしょうか。
サンプルまで書いていただければベストアンサ-はもちろん、高ポイントを差し上げます。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2014/11/14 12:29:19

ベストアンサー

id:rouge_2008 No.2

回答回数595ベストアンサー獲得回数351

「hoge.php」の以下の部分でコマンドとして実行しているようですので、定義済みの変数である$argvを使っているのではないかと思います。

$abc = $_POST['abc'];
$command = $php_path . ' ' . $script_path . ' ' . $abc . ' >/dev/null 2>&1 &';
exec( $command );

・$argv PHP マニュアル 言語リファレンス 定義済の変数
http://php.net/manual/ja/reserved.variables.argv.php

コマンドラインから実行したときに、 現在のスクリプトに渡されたすべての引数の配列が含まれます。

注意: 最初の引数 $argv[0] は常に、スクリプトの実行に使う名前となります。

※「$argv の例」の入力および出力例を確認してもらえると分かりますが、引数として指定した順番で$argvに代入される点に注意してください。

新しく「name="efg"」の項目を追加して使用したい場合は、$abcと同じように実行するコマンドに引数として渡して、「bobubobu.php」の側では受け取った値の処理を追加すれば利用できるようになると思います。

・hoge.php

$abc = $_POST['abc'];
$efg = $_POST['efg'];
$hij = $_POST['hij'];
$kln = $_POST['kln'];
$command = $php_path . ' ' . $script_path . ' ' . escapeshellarg($abc) . ' ' . escapeshellarg($efg) . ' ' . escapeshellarg($hij) . ' ' . escapeshellarg($kln) . ' >/dev/null 2>&1 &';

/*
 * 次のように書くと引数に一つずつ指定する必要がないので面倒が減ります。
$args = array($_POST['abc'], $_POST['efg'], $_POST['hij'], $_POST['kln']); /* 他にも追加したい項目があればここに追記します。 */
$paramarr = array_map("escapeshellarg", $args);
$paramstr = implode(' ', $paramarr);
$command = $php_path . ' ' . $script_path . ' ' . $paramstr . ' >/dev/null 2>&1 &';
 */

exec( $command );

・bobubobu.php

$abc = $argv[1];
$efg = $argv[2];
$hij = $argv[3];
$kln = $argv[4];


※ほぼコメントのままですが、TransFreeBSDさんから指摘のあった件で「escapeshellarg()」の処理を追加してあります。(環境によっては問題が発生する場合がある事に注意してください。)

id:ykhpno1

ありがとうございました!
ばっちり思ったような形になりました。感謝です!

2014/11/14 12:28:57

その他の回答1件)

id:yoneto164 No.1

回答回数813ベストアンサー獲得回数94

hoge.phpには、
require( dirname( __FILE__ ) . '/config.php' );
とあるのですよね?
config.php の中に bobubobu.php は無いのですよね?

なぜ bobubobu.php が動作していると思われたのか分かりませんが、
そもそも bobubobu.php は動作しているのでしょうか?
また bobubobu.php が動作していると思った経緯を教えていただければ何か分かるかも知れません。

id:rouge_2008 No.2

回答回数595ベストアンサー獲得回数351ここでベストアンサー

「hoge.php」の以下の部分でコマンドとして実行しているようですので、定義済みの変数である$argvを使っているのではないかと思います。

$abc = $_POST['abc'];
$command = $php_path . ' ' . $script_path . ' ' . $abc . ' >/dev/null 2>&1 &';
exec( $command );

・$argv PHP マニュアル 言語リファレンス 定義済の変数
http://php.net/manual/ja/reserved.variables.argv.php

コマンドラインから実行したときに、 現在のスクリプトに渡されたすべての引数の配列が含まれます。

注意: 最初の引数 $argv[0] は常に、スクリプトの実行に使う名前となります。

※「$argv の例」の入力および出力例を確認してもらえると分かりますが、引数として指定した順番で$argvに代入される点に注意してください。

新しく「name="efg"」の項目を追加して使用したい場合は、$abcと同じように実行するコマンドに引数として渡して、「bobubobu.php」の側では受け取った値の処理を追加すれば利用できるようになると思います。

・hoge.php

$abc = $_POST['abc'];
$efg = $_POST['efg'];
$hij = $_POST['hij'];
$kln = $_POST['kln'];
$command = $php_path . ' ' . $script_path . ' ' . escapeshellarg($abc) . ' ' . escapeshellarg($efg) . ' ' . escapeshellarg($hij) . ' ' . escapeshellarg($kln) . ' >/dev/null 2>&1 &';

/*
 * 次のように書くと引数に一つずつ指定する必要がないので面倒が減ります。
$args = array($_POST['abc'], $_POST['efg'], $_POST['hij'], $_POST['kln']); /* 他にも追加したい項目があればここに追記します。 */
$paramarr = array_map("escapeshellarg", $args);
$paramstr = implode(' ', $paramarr);
$command = $php_path . ' ' . $script_path . ' ' . $paramstr . ' >/dev/null 2>&1 &';
 */

exec( $command );

・bobubobu.php

$abc = $argv[1];
$efg = $argv[2];
$hij = $argv[3];
$kln = $argv[4];


※ほぼコメントのままですが、TransFreeBSDさんから指摘のあった件で「escapeshellarg()」の処理を追加してあります。(環境によっては問題が発生する場合がある事に注意してください。)

id:ykhpno1

ありがとうございました!
ばっちり思ったような形になりました。感謝です!

2014/11/14 12:28:57
  • id:rouge_2008
    「hoge.php」の以下の部分でコマンドとして実行しているようですので、定義済みの変数である$argvを使っているのではないかと思います。

    $abc = $_POST['abc'];
    $command = $php_path . ' ' . $script_path . ' ' . $abc . ' >/dev/null 2>&1 &';
    exec( $command );

    ・$argv PHP マニュアル 言語リファレンス 定義済の変数
    http://php.net/manual/ja/reserved.variables.argv.php


    新しく「name="efg"」の項目を追加して使用したい場合は、$abcと同じように実行するコマンドに引数として渡して、「bobubobu.php」の側では受け取った値の処理を追加すれば利用できるようになると思います。

    $abc = $_POST['abc'];
    $abc = $_POST['efg'];
    $command = $php_path . ' ' . $script_path . ' ' . $abc . $efg . ' >/dev/null 2>&1 &';
    exec( $command );


    ・bobubobu.php
    $abc = $argv[1];
    $abc = $argv[2];
  • id:rouge_2008
    コピーして変数名を変更するのを忘れていたので訂正します・・・

    ・bobubobu.php
    $abc = $argv[1];
    $efg = $argv[2];

    ※「bobubobu.php」では上記のようにそのまま$abc、$efgで入れていますが、任意の変数名にしても動作すると思います。

    ※「hoge.php」での代入先変数およびコマンドの引数間の空白が抜けていたのでさらに修正します。

    $abc = $_POST['abc'];
    $efg = $_POST['efg'];
    $command = $php_path . ' ' . $script_path . ' ' . $abc . ' ' . $efg . ' >/dev/null 2>&1 &';
    exec( $command );
  • id:ykhpno1
    >>rouge_2008さん

    rouge_2008さんの方法でうまくいきそうです、ありがとうございます。
    おかげさまでいろんな事がわかってきました。
    わかりかけていることを確信するために追加で教えていただきたいのですが、
    あらたに「name="hij"」と「name="kln"」という値もbobubobu.phpに登場させたい場合、
    hoge.phpの例の文字列
    $command = $php_path . ' ' . $script_path . ' ' . $abc . ' ' . $efg . ' >/dev/null 2>&1 &';
    はどうなりますでしょうか。

    また、コメント欄ではなく回答欄にお返事をください。
    ベストアンサ-かつポイントを送らせていただきたいのです。
    よろしくお願いいたします。
  • id:TransFreeBSD
    名前が変わっても同様に追加していきます。
    ちなみに今のままだとシェルコードインジェクションが出来ますので以下のようにしておいた方が身のためです。
    >||
    $command = $php_path . ' ' . $script_path . ' ' . escapeshellarg($abc) . ' ' . escapeshellarg($efg) . ' ' . escapeshellarg($_POST['hij']) . ' ' . escapeshellarg($_POST['kln'];) . ' >/dev/null 2>&1 &';
    ||<
    bobubobu.phpの変更もお忘れ無く。
  • id:a-kuma3
    php のマニュアルだと、ここを見ると良いです。
    http://php.net/manual/ja/reserved.variables.argv.php
  • id:rouge_2008
    a-kuma3さん、そのマニュアルページは上のコメント内に書いています・・・

    ykhpno1さん、すみません。回答は少し待ってください。


    少し疑問点が出てきてしまいました。
    通常はレンタルサーバーでHTTPD(Apache)の言語設定はどうなっているんでしょう?
    ※「escapeshellarg()」に日本語などのマルチバイトを渡した時に空白になる問題の関連です。

    Linux系のOSではhttpdファイルに設定するようですが、レンタルサーバーだとこの対処方法は無理だと思いますので・・・

    ・CentOSでApacheを日本語ロケール(ja_JP.utf8)で起動する
    http://maeda.farend.ne.jp/blog/2010/01/05/apache-httpd-lang/
  • id:a-kuma3
    >a-kuma3さん、そのマニュアルページは上のコメント内に書いています・・・
    あ、また、やってしまった X-|

  • id:TransFreeBSD
    >あるサンプルプログラムの事で
    とあるので特定のレンタルサーバーの話とかでもない気がしますがどうでしょう?

    >※「escapeshellarg()」に日本語などのマルチバイトを渡した時に空白になる問題の関連です。
    そんな問題が...

    ま、ぶっちゃけ言えば、こういう設計がそもそもアレで、勉強のサンプルとしてどうかなと思わなくもない。
    #セキュリティとか内部動作を考慮とか泥臭い部分の勉強として、ならまあという気はするけど、そういう話ではないだろうし。
  • id:rouge_2008
    返信ありがとうございます。
    問題が発生する可能性がある事とその対処方法を知って置いた方がいいかなと思ったものですから・・・
    でも、共用ならサーバー側で対応してくれるような気がしますし、VPSや専用ならhttpdファイルでの設定が可能ですから大丈夫かもしれません。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません