Как разобрать строку логической логики в PHP


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

'true && true || false'

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

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

Author: TheOddLinguist, 2010-05-04

4 answers

Просто наткнулся на этот вопрос, но, будучи довольно неуверенным в использовании 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.

 28
Author: gpmcadam, 2011-01-25 14:19:57

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

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

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

 4
Author: Rich Adams, 2010-05-03 21:15:24

Давайте предположим, что 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)

 2
Author: VolkerK, 2010-05-03 21:14:38

(строка) истина&&истина||ложь

 -3
Author: wiiman, 2010-05-04 04:15:40