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
평가자를 작성하는 것은 복잡한 작업이지만 이 질문 에 대한 ircmaxell의 답변을 확장 하여 문자열 및 / 또는 문자열도 처리 할 수 ​​있습니다. 또는 같은에서 계산 엔진에서 볼 PHPExcel
마크 베이커

1
"깨끗한"솔루션은 다른 기능을 가진 클래스를 설정하고 여러 파일에 포함시키는 것입니다. 코드를 문자열로 저장하고 나중에 평가하기 위해 PHP는를 제공합니다 eval().

1
@MarkBaker에게 감사합니다. 이것들을 살펴볼 수도 있습니다. 내가 원하는 것을 정확히 아닙니다. eval ()을 사용하고 싶지 않습니다.이 수식은 사용자가 사용하기 때문에 너무 위험 할 수 있습니다. 이것은 더 무모해야합니다.
Pawel Jankowski

3
"내부 플랫폼 효과"생성에주의하십시오. 지금까지 우리가 보여준 것을 상상하기가 어렵 기 때문에 많은 코드 줄을 저장할 수 있습니다. 모든 PHP 구문을 선호하지는 않지만 모든 PHP 개발자 (또는 C ++ 또는 Java 개발자)가 이해할 수있는 표준입니다. 따라서 이것은 시도하기에 재미있는 것처럼 보이지만 소규모 프로젝트에서 먼저 실험하는 것이 좋습니다. 그것이 작동한다면, 큰 프로젝트에 적용하는 것을 고려하십시오.
John Doe

1
RPN 평가자는 작성 및 유지 보수가 더 간단한 작업입니다. 그것은 매우 강력하고 잘못 될 수있는 일이 적습니다. 언어 생각으로는 사용자에게 덜 친숙합니다.
Scara95

답변:


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.