Как разобрать строку логической логики в PHP
Я создаю класс PHP с закрытой функцией-членом, которая возвращает строковое значение, такое как:
'true && true || false'
К публичной функции-члену. (Эта строка является результатом некоторого сопоставления регулярных выражений и поиска свойств.) Что я хотел бы сделать, так это заставить PHP проанализировать возвращаемую логику и заставить вышеупомянутую общедоступную функцию возвращать, является ли логический результат проанализированной логики истинным или ложным.
Я попробовал eval(), но не получил никакого результата вообще. Я попытался ввести логическое значение возвращается...но нет никакого способа типизировать операторов...хе-хе, есть какие-нибудь идеи? (Дайте мне знать, если вам понадобится дополнительная информация.)
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
.
eval()
будет отлично работать для этого, но помните, что вы должны сказать ему, чтобы он что-то вернул.
$string = "true && true || false";
$result = eval("return (".$string.");"); // $result will be true
Также убедитесь, что вы очистили все пользовательские данные, если помещаете их непосредственно в eval()
.
Давайте предположим, что 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)
(строка) истина&&истина||ложь