phpの構文チェックに関する質問です。

evalを使って文字列を式として評価して実行したいと考えていますが、文字列がphpとして構文エラーにならないか、evalで実行する前に調べてから実行したいと考えているのですが、チェック用の関数などが見当たりません。
何か構文チェク用の関数があればお教えいただけますでしょうか。もしくは、それに変わる手法が何かあればお教えいただけますでしょうか。
以上、よろしくお願いいたします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2011/12/02 12:13:08
  • 終了:2011/12/06 14:58:21

ベストアンサー

id:kodairabase No.3

kodairabase回答回数661ベストアンサー獲得回数802011/12/02 14:09:07

ポイント50pt

PECLが利用できれば、runkit_lint関数で構文チェックができます。
http://php.net/manual/ja/function.runkit-lint.php


素のままのPHPなら、以下のようにしてできます。

<?php
$MyErrorNo = 0;
function myErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    global $MyErrorNo;
    $MyErrorNo = $errno;
    echo "$errmsg ($errno) occured.";
}

// $strを評価する
// エラーがあればエラー番号を返す。エラーが無ければ0。
function my_lint($str) {
    global $MyErrorNo;
    set_error_handler('myErrorHandler');
    error_reporting(E_ALL);
    @eval($str);
    restore_error_handler();
    return $MyErrorNo;
}

//メインプログラム
$str = '$x = 8 / 0;';
my_lint($str);
?>
id:n_maco2

この関数が使えれば一番楽ですね、ありがとうございます。

ただ、ご記載いただいたPHPのコードのほうは、これはやはり$strを実行してしまいませんか?できれば実行前に確認したいと考えています。

諸々ご回答ありがとうございました。

2011/12/02 14:35:12

その他の回答(2件)

id:HowAreYou No.1

HowAreYou回答回数91ベストアンサー獲得回数172011/12/02 12:46:16

ポイント25pt

eval ですいませんが。

<?php
$r = @eval('invalid code') ;
echo $r === FALSE ? 'パースエラー' : 'Ok.' ;


http://www.php.net/manual/ja/function.eval.php

id:n_maco2

回答ありがとうございます。
ですがこのコードだと、問題ないコードの場合は、evalが実行されてしまいますよね。中途半端に実行されるのを防ぎたいという意図なので、これだと目的を達成できないかなと・・(もちろんERRORなら中途半端にも実行されることはありませんが、Warningなら実行されてしまうと思います)

2011/12/02 13:38:55
id:JULY No.2

JULY回答回数966ベストアンサー獲得回数2472011/12/02 13:57:42

ポイント34pt

php コマンドを呼び出す事が許されるのであれば、-l もしくは --syntax-check で確認できます。

PHP: オプション - Manual

$ php -l test.php
No syntax errors detected in test.php

Web アプリケーションの機能として実装するのであれば、system() 関数を使って、引数でもらえる終了ステータスが 0 であれば OK、といった判断が出来ると思います。

PHP: system - Manual

id:n_maco2

なるほど、ありがとうございます。
しかし、この方法だとsafemodeとか別の問題を起こしてしまいそうな気がしますので、ちょっと面倒な気がしますね。
でもありがとうございます、検討させていただきます。

2011/12/02 14:31:19
id:kodairabase No.3

kodairabase回答回数661ベストアンサー獲得回数802011/12/02 14:09:07ここでベストアンサー

ポイント50pt

PECLが利用できれば、runkit_lint関数で構文チェックができます。
http://php.net/manual/ja/function.runkit-lint.php


素のままのPHPなら、以下のようにしてできます。

<?php
$MyErrorNo = 0;
function myErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    global $MyErrorNo;
    $MyErrorNo = $errno;
    echo "$errmsg ($errno) occured.";
}

// $strを評価する
// エラーがあればエラー番号を返す。エラーが無ければ0。
function my_lint($str) {
    global $MyErrorNo;
    set_error_handler('myErrorHandler');
    error_reporting(E_ALL);
    @eval($str);
    restore_error_handler();
    return $MyErrorNo;
}

//メインプログラム
$str = '$x = 8 / 0;';
my_lint($str);
?>
id:n_maco2

この関数が使えれば一番楽ですね、ありがとうございます。

ただ、ご記載いただいたPHPのコードのほうは、これはやはり$strを実行してしまいませんか?できれば実行前に確認したいと考えています。

諸々ご回答ありがとうございました。

2011/12/02 14:35:12
  • id:y-kawaz
    そもそもevalなんてものを必要とする設計を考えなおしたほうが良いと思います。
    特にそれがユーザの入力を利用するようなものであればなおさら使うべきではないです。
  • id:n_maco2
    おっしゃるとおりですね、しかもユーザー入力に依存しています。
    が、諸事情で他の設計がやりづらく・・せめて文法チェックや入力値の型チェックを厳密にやって凌げるかどうか、検討をしているところです。
    ご忠告ありがとうございます。

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません