代码之家  ›  专栏  ›  技术社区  ›  Mawg says reinstate Monica

在PHP(reg exp?)

  •  0
  • Mawg says reinstate Monica  · 技术社区  · 7 年前

    在浏览器端,用户将输入一个布尔查询,它可能会变得复杂,我想将其转换为一个SQL SELECT 陈述。

    用户将沿以下行输入文本字符串 a AND ((b OR c) OR (not d)) . 如我所说,这是一个任意文本字符串,包含一个布尔表达式。

    它是软件招聘人员的,所以A、B、C、D等都是技能,如C、C++、UML、Python等,所以前面的例子可能实际上是读的。 C++ AND ((UML OR Python) OR (not Perl)) .

    我想扩展到(在本例中) SELECT * FROM candidates WHERE skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)) .

    我可以准备 选择 陈述,但我如何翻译(例如) C++和((UML或Python)或(不Perl)) skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)) 在PHP中,对任意一个带有任意数量方括号的布尔表达式都可以这样做吗?

    0 回复  |  直到 7 年前
        1
  •  1
  •   Arno Hilke    7 年前

    我从您发布的示例中进行了以下观察:您所要做的只是替换如下标记 C++ 带着一个形状的标记 skill=C++ ,查询的其余部分保持不变。如果这并不总是正确的,您可能需要一个更复杂的解决方案,但如果这对您来说已经足够了,则应使用以下方法:

    $expr = 'C++ AND ((UML OR Python) OR (not Perl))';
    
    // remove tokens that will not be replaced, here `(`, `)`, and `not`
    $trimmed = str_replace(['(', ')', 'not'], ['', '', ''], $expr);
    
    // split string based on the keywords `AND` and `OR` (case insensitive)
    // keywords will also not be replaced
    $tokens = preg_split('/AND|OR/i', $trimmed);
    
    // create replacement tokens without leading/trailing whitespace
    $replacementTokens = [];
    foreach ($tokens as &$token) {
        $token = trim($token);
        $replacementTokens[] = "skill=$token";
    }
    
    // replace tokens and construct the query
    $where = str_replace($tokens, $replacementTokens, $expr);
    $query = "SELECT * FROM candidates WHERE $where";
    

    如前所述,如果您需要更复杂的行为,此解决方案可能不起作用。您可能还需要扩展关键字列表。但是对于您提供的简单用例,它避免了实际解析查询的需要。

    最后一点,请确保对用户输入进行了清理,这样就不会受到SQL注入的影响。

    推荐文章