PHPで文字列式を使用してデータセットを評価する


9

アプリケーションの一部の条件を更新する必要がありました。評価するデータセットがあり、アプリケーションで次のようにハードコードされています。

$arr = array(
'a' => 'apple',
'b' => 'orange',
'c' => 1,
'd' => 2,
'e' => 5,
'f' => 'green',
'g' => 'red',
'h' => 'yellow',
)

$res1 = ($arr['a'] == 'apple') ? TRUE : FALSE;
$res2 = (($arr['b'] == $arr['f']) && ($arr['c'] < $arr['d']) ? TRUE : FALSE;
$res3 = (($arr['e'] == '5') && $res2) ?TRUE : FALSE;

等々...

多くの場所で維持するのは悪夢です。

基本的に私が探しているのは、クエリ文字列を渡してデータを評価する方法を作ることです。まず、単純な数式を配列として定義できます

$formula = ['a', '=', 'apple'];

function query($formula, $arr) {
    switch ($formula[1]) {
        case '=':
            return ($arr[$formula[0]] == $formula[2]);
        case '!=':
            return ($arr[$formula[0]]!= $formula[2]);
        case '>':
            return ($arr[$formula[0]] > $formula[2]);
        case '<':
            return ($arr[$formula[0]] == $formula[2]);
    }
}

これを拡張して再帰的に呼び出すことができます

$formula = [['a','=','apple'], 'AND', ['e','<','10']]

しかし、私が本質的に探しているのは、数式を文字列として保存することです:

"((([a]="orange") OR ([c]<"4")) AND ([g]="red"))"

ここで、[]は配列キーを識別します

または多分Excelのようなもの

"AND(OR(IF('a'='orange'),IF('c'<4)),IF('g'='red'))"

これを行うためのクリーンな解決策はありますか?そのためのライブラリ全体を構築する方法を考えています。

毎回コードに新しい条件を追加したくありません。彼らはすでにすべてのアプリケーションです。それを構成に保管し、1か所で拡張または変更することをお勧めします。

どんな助けも大歓迎です。


1
エバリュエーターを書くのは複雑な作業ですが、この質問に対するircmaxellの回答を拡張して、文字列や文字列を処理することも検討してください。またはPHPExcelの
マークベイカー

1
「クリーン」な解決策は、さまざまな機能を持つクラスを設定し、それをいくつかのファイルに含めることだと思います。コードを文字列として保存し、後で評価するために、PHPはを提供していますeval()

1
@MarkBaker、ありがとうございます。私があなたが何を探しているのか正確ではありません。eval()は本当に使いたくありません。これらの式はユーザーが使用するため、これは危険すぎる可能性があります。これはもっと簡単なはずです。
Pawel Jankowski

3
「内部プラットフォーム効果」を作成することに注意してください。これまでに示してきた内容から、多くのコード行を保存してしまうことを想像するのは困難です。PHPのすべての構文を好むわけではありませんが、PHP開発者(またはC ++またはJava開発者)が理解できる標準です。したがって、これは試すのは楽しいことのように思われますが、小規模なサイドプロジェクトで最初に実験することをお勧めします。そこで機能する場合は、大きなプロジェクトに組み込むことを検討してください。
John Doe

1
RPNエバリュエーターは、記述と保守が簡単なタスクです。それはかなり強力であり、あなたが間違ってしまう可能性があるものはほとんどありません。言語としてはユーザーフレンドリーではありません。
Scara95 2015年

回答:


1

したがって、これは簡単な解決策にすぎませんが、今のところ私には問題ありません。

$arr = array('a' => 'red','b' => 'blue');

$formula = ['[a]', '=', 'red'];

式に[a]がある場合、それは配列キーとして扱われます。

function query($formula, $arr) {

    $query_operator=$formula[1];

    if (is_array($formula[0])) {
        //recursive call
        $query_left = query($formula[0], $arr);
    } else {
        //extracting string between brackets
        preg_match("/\[([^\]]*)\]/", $formula[0], $match);
        $query_left = $match ? $arr[($match[1])] : $formula[0];
    }

    if (is_array($formula[2])) {
        //recursive call
        $query_right = query($formula[2], $arr);
    } else {
        //extracting string between brackets
        preg_match("/\[([^\]]*)\]/", $formula[2], $match);
        $query_right = $match ? $arr[($match[1])] : $formula[2];
    }


    switch ($query_operator) {
        case '=':
            return ($query_left == $query_right);
        case '!=':
            return ($query_left != $query_right);
        case '>':
            return ($query_left > $query_right);
        case '<':
            return ($query_left == $query_right);
        case 'AND':
            return ($query_left && $query_right);
        case 'OR':
            return ($query_left || $query_right);
    }
}

このソリューションでは、次のような数式で機能します。

$formula = [['[a]', '=', 'red'], 'AND', ['[b]', '=', 'blue']];

それは私が欲しかったものではありませんが、仕事をし、それほどひどくありません(私は願っています)。入力チェックとエラー処理が必要ですが、これは単なる例です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.