PHPで "「こんにちは、世界」を英語で言うと「<?php echo 'hello world!' ?>」です。" を文字列として読み込み、「'hello world!'」を出力することは可能でしょうか?

HTMLテンプレートを読み込んで出力するシステムをPHP5で作ったのですが、テンプレート内にもPHPコードを埋め込みたいと言う要望をクライアントから出されてどう実現すればいいのかわからずに困っています;

回答の条件
  • 1人50回まで
  • 登録:
  • 終了:2008/08/27 05:40:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Mook No.3

回答回数1314ベストアンサー獲得回数393

ポイント60pt

だいたいどの言語も同じような仕様を持っていますが、PHPで文字列をコードとして実行するのは、

eval()になります。


たとえばテンプレートファイルを

sample.tmp

<html>
<head>
</head>
<body>
_PHP for( $i=0 ; $i<10 ; $i++ ) echo "Hello World\n<BR>";
</body>
</html>

としておいて、

<?php
    $handle = @fopen("sample.tmp", "r");
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle, 4096);
            if( substr( $buffer, 0, 4 ) == "_PHP" ) {
                eval( substr( $buffer, 4, -1 ) );
            } else {
                echo $buffer;
            }
        }
        fclose($handle);
    }
?>

とすれば、テンプレート内で _PHP で始まる行をコードとして処理します。

この結果は"Hello World" が十回画面に表示されます。

id:jazzmine

ありがとうございます。

eval(); は知りませんでした。大変助かりました。

また、下記コメント欄にもあるようにセキュリティ面の忠告も

ありがとうございます。テンプレートはクライアントのみが

修正するのですが、充分気をつけていただくよう伝えておきます。

2008/08/27 05:25:01

その他の回答3件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント5pt

いったん ~~~.phpのファイルを作成して、それを実行するようにしたらいかがでしょうか?

id:jazzmine

ありがとうございます。

そのような処理を考えているのですが、効率的な処理の流れを思い浮かべずに困っています。

2008/08/27 05:18:49
id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301

ポイント5pt
<?php echo "'hello world!'" ?>

上記のようにダブルクォーテーションで囲んでもらえば出来るはずですが

この程度の超初心者的な事であればphpでシステムを作って商売になさっておられる方が

相談にこられるとも思いませんので、もっともっと深い部分で躓いておられるのだと思いますが

どのようなシステムで、どのようなテンプレートをお使いになっていて、

ハローワールドの記述はどこで行っていてなどなど、システムについて具体的に書けませんか?

id:jazzmine

ありがとうございます。

説明不足で恐れ入ります。

下記、MookさんのようなテンプレートをPHPが読み込む際にPHP箇所を

処理させるロジックを考えていました。

2008/08/27 05:22:08
id:Mook No.3

回答回数1314ベストアンサー獲得回数393ここでベストアンサー

ポイント60pt

だいたいどの言語も同じような仕様を持っていますが、PHPで文字列をコードとして実行するのは、

eval()になります。


たとえばテンプレートファイルを

sample.tmp

<html>
<head>
</head>
<body>
_PHP for( $i=0 ; $i<10 ; $i++ ) echo "Hello World\n<BR>";
</body>
</html>

としておいて、

<?php
    $handle = @fopen("sample.tmp", "r");
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle, 4096);
            if( substr( $buffer, 0, 4 ) == "_PHP" ) {
                eval( substr( $buffer, 4, -1 ) );
            } else {
                echo $buffer;
            }
        }
        fclose($handle);
    }
?>

とすれば、テンプレート内で _PHP で始まる行をコードとして処理します。

この結果は"Hello World" が十回画面に表示されます。

id:jazzmine

ありがとうございます。

eval(); は知りませんでした。大変助かりました。

また、下記コメント欄にもあるようにセキュリティ面の忠告も

ありがとうございます。テンプレートはクライアントのみが

修正するのですが、充分気をつけていただくよう伝えておきます。

2008/08/27 05:25:01
id:pahoo No.4

回答回数5960ベストアンサー獲得回数633

ポイント30pt

こんな感じでどうでしょうか。

スクリプトは $instr に入れるとします。複数行にも対応しています。

<?php
$instr =<<< EOT
<?php echo 'hello world!'; ?>
EOT;

preg_match("/<\?(php)?(.*)\?>/ms", $instr, $arr);
$e = isset($arr[2]) ? $arr[2] : '';
eval($e);
?>

ただし、evalでエラーが発生したとき(入力したスクリプトが間違っているとき)の処理をしていません。

これに関連しますが、クロスサイトスクリプティング攻撃を受ける可能性が高いプログラムですので、実装に当たっては十分にご注意ください。

id:jazzmine

ありがとうございます。

実際はもっと複雑な処理になるのですが、スクリプトが

間違っている場合の対応はなかなか厳しいですね。

また、クライアントが埋め込んだコードに脆弱性があるかもしれないので

その辺も充分注意してもらうよう伝えておきます。

2008/08/27 05:29:41
  • id:Mook
    ん、なにか、勘違いしていたかな?

    とんちんかんな回答でしたら、無視してください。
  • id:jazzmine
    質問者です。

    > ん、なにか、勘違いしていたかな?

    いえ、多分、私が求めていた答えそのものです。

    また今晩確認させていただきます。ありがとうございました。
  • id:kn1967
    このレベルの質問に対して eval を回答するのは
    セキュリティ的にどうなのかしら?
  • id:Mook
    セキュリティ云々は質問者さんの責任でやってもらうとして、
    http://ja.wikipedia.org/wiki/Eval
    あたりをご一読いただいた方がよいでしょうか。

    件の殺人事件での質問もありましたからね、回答も気軽にはできないということでしょうか・・・。
  • id:kn1967
    気軽にっていうか・・・。
    数十円で解説付きのコードを書いてくれると思っている人は非常に増えたでしょうね。

    それはまぁ良しとしても
    低スキルで意味を理解せずに納品物に使っているような場面も多い事でしょうから
    世に出回っているものの品質低下は・・・
    品質低下よりも踏み台にされたりしたら被害は・・・。
    文章見れば働くものとしてのスキルは一目でしょ?

    私にも無いとは言いませんが親切と自己満足・・・。
    この違いは非常に大きいのではありませんかねぇ。
  • id:Mook
    うーん、親切と自己満足ですか。

    「質問者さんの問題解決になれば」という親切心(1)と、
    私的にはパズルのような感覚で「問題を解決できた」という功名心的な自己満足(2)のために
    回答している感じがします。
    その上で、質問した方から「たすかった」とか「ありがとう」という言葉(3)があれば、
    とても嬉しい気分になります。ポイントよりも、この一言がうれしいですね。

    私としては
    (1):(2):(3)=1:2:2
    くらいかなぁ。そう考えると、回答するのはほとんど自分のためですね。
  • id:kn1967
    「たすかった」とか「ありがとう」は確かに一番嬉しいですね。
    ポイントは正直オマケ。

    そうこうしているうちに、自己満足の権化みたいな回答者が現れましたね。
    以前はKUで始まる5文字のアカウントがいましたが今はpaで始まる5文字・・・。
    かの人は忠告無視ですから・・・。
    「実装に当たっては十分にご注意ください。」って・・・。
    http://q.hatena.ne.jp/1219706023 でもどんな危険な回答を書いているやら・・・。
  • id:Mook
    質問者様の質問とは関係のないコメントが長くなってすみません。

    eval は確かに強力な関数ですが、コメントにありますようにセキュリティ的に
    慎重に扱うべきものですので、テンプレートの管理等に関してもセキュリティ
    に配慮ください。

    特に公開サーバ上に置く場合、テンプレートの管理は外部からのアクセスができ
    ないよう、設定等の確認をお勧めします。
  • id:galenos
    > kn1967
    おまえが一番スキル低いくせに、質問者にポイント配分まで命令するとは、いやはや。
    厚顔無恥とは、おまえを指す言葉だな。
  • id:jazzmine
    多数のコメントありがとうございます。

    今回は eval で対処させていただこうと思いますが
    セキュリティ上の懸念は確かにありますね。

    クライアントの書いたコードに脆弱性がある場合や間違った
    スクリプトを書かれている場合への対応はかなり厳しい(キリが無い)と思います。

    極力使わないようにお願いするのが一番賢明かもしれません。
    また、使用する際は充分気をつけていただくよう伝えておきます。

    ありがとうございました。

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

トラックバック

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

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

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