2011-12-13 101 views
1

这是一个棘手的解释。我有一个关联数组,我想运行一组规则来返回true或false。匹配式(SQL'ish)针对PHP阵列返回真或假

我在想,如果有什么地方让我比较的规则对数组库(或一组)。几乎像SQL exept我有记录,我只需要看看SQL是否会返回它。

例如:

$subject = array('name' => 'John Smith', 'age' => '44'); 
$formula = "name LIKE 'John%' AND (age = 44 OR age = 45)"; 
if(match($formula, $subject)) 
return true; 
else 
return false; 

主题阵列是不是从一个数据库,它实际上是从一个表单提交,否则我会运行的SQL,如果返回正确的记录那么这将是真实的。此外,这是我想用很多可能不同的关联数组,所以添加到表中,然后运行查询来获取相同的记录是不可能的。基本上我不能使用数据库。

+0

这里的困难将被解析`$ formula` - 哪里该字符串从何而来?你可以改变格式,或者(理想情况下)使用数组? – DaveRandom 2011-12-13 17:09:28

回答

0

如果你想要一个表达式解析,好像它是SQL,然后使用SQL语法分析程序....

$subject = array('name' => 'John Smith', 'age' => '44'); 
$formula = "'name' LIKE 'John%' AND ('age' = '44' OR 'age' = '45')"; 
$result=try_expression($subject, $formula); 

function try_db_expression($subject, $formula) 
{ 
$keys=array_keys($subject); 
$vals=array_values($subject); 

foreach ($keys as $k=>$v) { 
    $keys[$k]='/\b' . mysql_real_escape_string($v) . '\b/i'; 
} 
foreach ($vals as $k=>$v) { 
    $vals[$k]=mysql_real_escape_string($v); 
} 
$test=preg_replace($keys, $vals, $subject); 
$res=mysql_query("SELECT ($test) AS evald"); 
if ($r=mysql_fetch_assoc($res)) return $r['evald']; 
return false; 
} 

基本上我不能使用一个数据库

然后你必须构建你自己的解析器(不是真的 - 你可以使用PHP的eval--但你需要将LIKE运算符映射到PHP函数)。

1

也许你可以做这样的事情?

function match ($subject, $formula) { 
    extract($subject); 
    foreach ($formula as $rule) { 
    if (!eval("return $rule;")) return FALSE; 
    } 
    return TRUE; 
} 

$formula = array(
    'substr($name,0,4) == "John"', 
    '$age == 44 OR $age == 45' 
); 
$subject1 = array('name' => 'John Smith', 'age' => '44'); 
$subject2 = array('name' => 'Bob Jones', 'age' => '42'); 

var_dump(match($subject1, $formula)); // bool (TRUE) 
var_dump(match($subject2, $formula)); // bool (FALSE) 

这种方法意味着您的规则可以像您喜欢的那样复杂;例如,上述$formula可以压缩成这一个规则:

$formula = array(
    'substr($name,0,4) == "John" AND ($age == 44 OR $age == 45)' 
); 

因为它的工作方式,多条规则有效地具有AND关系 - 只要一个规则失败,函数返回false。

你可以写东西喜欢,使用任何你喜欢的PHP函数,只要它是一个有效的比较表达式。

0

有这样几个实现。你基本上正在寻找“PHP中的LINQ”,并且它可以用于数组数据集。 PHPLinq

他们大多使用更ORM式查询方法,而不是SQL解析器。 (你可以从http://www.phpinsider.com/php/code/SafeSQL/http://pear.php.net/package/SQL_Parser得到)

你可以用递归正则表达式模仿SQL表达式。但是你不能用preg_match或_replace_callback轻松解析和处理它们。除非你真的只有这样简单的例子,否则我不会打扰。