サンプル・プログラム
プログラムの解説:計算式が正しいかどうか
しかし、この関数の仕様には注意が必要だ。文法エラーなどがあると、PHPそのものがダウンしてしまうからだ。
そこで、eval関数に通す前に、計算式が正しいかどうかをチェックするユーザー関数 check_expression を用意した。
0024: /**
0025: * 計算式が正しいかどうか調べる
0026: * @param string $expression 計算式
0027: * @return bool TRUE=正しい/FALSE=不正
0028: */
0029: function check_expression($expression) {
0030: //利用可能な数学関数
0031: static $table_math = array('abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'exp', 'fmod', 'log10', 'log', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh');
0032:
0033: $cnt = 0;
0034: $res = '';
0035: $len = mb_strlen($expression);
0036: $start = 0;
0037: while ($start < $len) {
0038: $c = mb_substr($expression, $start, 1);
0039: if (preg_match('/^[0-9¥+¥-¥*¥/¥. ]+$/i', $c) == 1) {
0040: $res .= $c;
0041: } else if ($c == '(') {
0042: $cnt++;
0043: } else if ($c == ')') {
0044: $cnt--;
0045: //関数かどうか調べる
0046: } else {
0047: $fstr = $c;
0048: $start++;
0049: if ($start >= $len) return FALSE;
0050: while ($start < $len) {
0051: $c = mb_substr($expression, $start, 1);
0052: if (preg_match('/^[a-z0-9]+$/i', $c) == 1) {
0053: $fstr .= $c;
0054: } else {
0055: $res = FALSE;
0056: foreach ($table_math as $val) {
0057: if (preg_match("/{$val}/i", $fstr) == 1) {
0058: $res = TRUE;
0059: break;
0060: }
0061: }
0062: if ($res == FALSE) return FALSE;
0063: if (preg_match('/^[¥( ]+$/i', $c) != 1) return FALSE;
0064: if ($c == '(') $cnt++;
0065: break;
0066: }
0067: $start++;
0068: }
0069: }
0070: $start++;
0071: }
0072:
0073: return $cnt == 0 ? TRUE : FALSE;
0074: }
本来、eval関数ではPHPの変数や組み込み関数も評価できるのだが、あえて配列 $table_math に定義した算術関数のみしか使えないように制約した。
また、括弧 (...) を数え、数が合わないとエラーを返すようにしてある。
コンパイル
コマンドラインから "bamcompile calclwin.bcp" を実行する。コンパイルが完了すると、"calcwin.exe" が生成されている。
"calcwin.exe" は、DLL不要で、単独で動作するEXEプログラムである。
参考サイト
- eval :PHP公式
- 文字列の計算式の計算結果を取得する