Đánh giá tập dữ liệu với công thức chuỗi trong php


9

Tôi được giao nhiệm vụ cập nhật một số điều kiện trong một ứng dụng. Tôi có một bộ dữ liệu được đánh giá và nó đã được mã hóa cứng trong ứng dụng theo cách sau:

$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;

và như thế...

Đó là một cơn ác mộng để duy trì ở nhiều nơi.

Những gì tôi về cơ bản đang tìm kiếm là thực hiện một số cách để vượt qua trong chuỗi truy vấn để đánh giá dữ liệu. Để bắt đầu, một công thức đơn giản có thể được định nghĩa là một mảng

$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]);
    }
}

Điều này sau đó có thể được mở rộng và được gọi đệ quy

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

nhưng điều tôi chủ yếu tìm kiếm là lưu trữ công thức chuỗi aa, như:

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

trong đó [] sẽ xác định các khóa mảng

hoặc có thể một cái gì đó giống như trong Excel

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

Có bất kỳ giải pháp sạch để làm điều này? Tôi có một ý tưởng làm thế nào để xây dựng toàn bộ thư viện cho nó, có thể trong tương lai.

Tôi không muốn thêm điều kiện mới vào mã mỗi lần. Họ đã có tất cả các ứng dụng. Sẽ tốt hơn để lưu trữ nó trong cấu hình và mở rộng hoặc sửa đổi ở một nơi.

Bất kỳ trợ giúp nhiều đánh giá cao.


1
Viết một người đánh giá là một nhiệm vụ phức tạp, nhưng bạn có thể xem xét việc mở rộng câu trả lời của ircmaxell cho câu hỏi này để xử lý và / hoặc cả chuỗi; hoặc nhìn vào công cụ Tính toán trong một cái gì đó như PHPExcel
Mark Baker

1
Tôi đoán một giải pháp "sạch" sẽ là thiết lập một lớp với các chức năng khác nhau và đưa nó vào một số tệp. Để lưu trữ mã dưới dạng chuỗi và đánh giá nó sau, PHP cung cấp eval().

1
Cảm ơn bạn @MarkBaker, tôi có thể có một cái nhìn về những điều đó. Không chính xác những gì tôi đang tìm kiếm bạn. Tôi không thực sự muốn sử dụng eval (), điều này có thể quá nguy hiểm, vì những công thức đó sẽ được sử dụng bởi người dùng. Điều này nên được đánh lừa hơn.
Pawel Jankowski

3
Xem ra để tạo ra một "hiệu ứng nền tảng bên trong". Thật khó để tưởng tượng từ những gì bạn đã cho chúng tôi thấy rằng cuối cùng bạn sẽ tiết kiệm được nhiều dòng mã. Bạn có thể không thích tất cả cú pháp của PHP, nhưng đó là một tiêu chuẩn mà bất kỳ nhà phát triển PHP nào (hoặc nhà phát triển C ++ hoặc Java) có thể hiểu được. Vì vậy, trong khi điều này có vẻ như là một điều thú vị để thử, nó có thể tốt hơn để thử nghiệm nó đầu tiên trên một dự án phụ quy mô nhỏ hơn. Nếu nó hoạt động ở đó, sau đó xem xét đưa nó vào dự án lớn.
John Doe

1
Một người đánh giá RPN sẽ là một nhiệm vụ đơn giản hơn để viết và duy trì. Nó là khá mạnh mẽ và có ít điều bạn có thể nhận được sai. Nó ít thân thiện với người dùng như một ngôn ngữ nghĩ.
Scara95

Câu trả lời:


1

Vì vậy, đây chỉ là giải pháp nhanh chóng, nhưng làm việc cho tôi ngay bây giờ.

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

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

Nếu có [a] trong công thức, nó sẽ được coi là khóa mảng.

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);
    }
}

Trong giải pháp này, nó sẽ hoạt động với công thức như:

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

Đó không phải là chính xác những gì tôi muốn, nhưng thực hiện công việc, và không quá khủng khiếp (tôi hy vọng). Nó cần một số kiểm tra đầu vào và xử lý lỗi, nhưng đây chỉ là một ví dụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.