Как разобрать строку булевой логики в PHP - PullRequest
10 голосов
/ 04 мая 2010

Я строю класс PHP с закрытой функцией-членом, которая возвращает строковое значение, такое как:

'true && true || false'

для публичной функции-члена. (Эта строка является результатом некоторых сопоставлений регулярных выражений и поиска свойств.) Я хотел бы, чтобы PHP проанализировал возвращаемую логику и чтобы указанная выше публичная функция возвращала, является ли логический результат проанализированной логики истинным или ложным. 1004 *

Я пробовал eval (), но я ничего не получил. Я пытался привести тип к булевому возвращению ... но нет способа добавить операторы к типу ... хе-хе Есть идеи? (Дайте мне знать, если вам нужна дополнительная информация.)

Ответы [ 3 ]

29 голосов
/ 25 января 2011

Просто наткнулся на этот вопрос, но, не зная, как использовать eval, я решил продолжать искать лучшее решение.

То, что я обнаружил, - это еще одно замечательное использование функции PHP filter_var, когда передается флаг FILTER_VALIDATE_BOOLEAN (, из которых много ).

Эта функция "одна строка", кажется, хорошо работает при безопасно преобразовании строкового (или другого) объекта в логическое значение:

<?php

/**
 * Uses PHP's `filter_var` to validate an object as boolean
 * @param string $obj The object to validate
 * @return boolean
 */
function parse_boolean($obj) {
    return filter_var($obj, FILTER_VALIDATE_BOOLEAN);
}

И, небольшое тестирование:

/**
 * Let's do some testing!
 */
$tests = array (
    "yes",
    "no",
    "true",
    "false",
    "0",
    "1"
);

foreach($tests as $test) {

    $bool = parse_boolean($test);

    echo "TESTED: ";
    var_dump($test); 

    echo "GOT: ";
    var_dump($bool);

    echo "\n\n";

}

Выход:

/*
TESTED: string(3) "yes"
GOT: bool(true)


TESTED: string(2) "no"
GOT: bool(false)


TESTED: string(4) "true"
GOT: bool(true)


TESTED: string(5) "false"
GOT: bool(false)


TESTED: string(1) "0"
GOT: bool(false)


TESTED: string(1) "1"
GOT: bool(true)
*/

Я не посмотрел достаточно глубоко, но возможно, что это решение где-то опирается на eval, однако я бы все равно не стал использовать их над простым eval, поскольку я предполагаю, что filter_var будет также обработайте дезинфекцию любого ввода перед тем, как пропустить его через eval.

3 голосов
/ 04 мая 2010

eval() будет отлично работать для этого, но помните, что вы должны сказать ему что-то вернуть.

$string = "true && true || false";
$result = eval("return (".$string.");"); // $result will be true

Также убедитесь, что вы дезинфицируете любые пользовательские входы, если помещаете их непосредственно в eval().

2 голосов
/ 04 мая 2010

Давайте предположим, что eval () является хорошим решением в вашем случае.

class Foo {
  private function trustworthy() {
    return 'true && true || false';
  }

  public function bar() {
    return eval('return '.$this->trustworthy().';');
  }
}

$foo = new Foo;
$r = $foo->bar();
var_dump($r);

отпечатков bool(true)

...