解析符号-字符串对以构建 sql 的 WHERE 子句的条件表达式

Parse symbol-string pairs to build conditional expressions for sql's WHERE clause

我需要 return 对符号+字符串。 我的应用程序包含具有特殊含义的符号。当前使用的有四个符号:&!%@,它们可以成对重复。

字符串示例:

%foo!bar
@baz
!bam@bat@bar
%bee@baa

我正在尝试将这些符号+字符串序列转换为我的 sql.

的 WHERE 条件表达式

这是我的代码演示: http://sandbox.onlinephpfunctions.com/code/e8d723fea139f3e8b683bcb6831a094a64a0ca53

我正在尝试 preg_split() 做一些接近我需要的事情,但我遇到了这个技术的几个问题。此外,随后的 for() 循环和 array_map() 不符合我的需要。

在这次尝试之后,我的代码被注释掉了,foreach() 将第一个字符划分为运算符,随后的非符号字符将成为字符串。

如果上述 link 不起作用,这是我的代码:

$individual_search = "";
$in = "%ciaooooooooo@noooooooo!sii";
$field = "provola";

if (strlen($in)>0) {
    switch($in[0]) {
        case "&":
        case "!":
        case "%":
        case "@":
            $ins = preg_split('/(&|!|%|@)/', $in, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
            //preg_match('/(&)|(!)|(%)|(@)/', $in, $ins);
            //var_dump($ins);
            /*for ($i=0; $i<6; $i=$i+2) {
                  echo $ins($i);
                  echo $ins($i+1);
              }*/
                        
            array_map(function ($x) {
                $i=0;
                echo $x[$i], $x[$i+1];
                $i=$i+2;
            }, $ins);
                     
            /*
                //var_dump($ins);
                foreach ($ins as $inss) {
                    $val = (substr($inss, 1));
                    switch($inss[0]) {
                        case "&":
                            $individual_search .= "AND {$field} = ''{$val}'' ";
                            break;
                        case "!":
                            $individual_search .= "AND ({$field} IS NULL OR {$field} != ''{$val}'') ";
                            break;
                        case "%":
                            $individual_search .= "AND {$field} LIKE ''{$val}%'' ";
                            break;
                        case "@":
                            $individual_search .= "AND {$field} NOT LIKE ''{$val}%'' ";
                            break;
                    } // end switch
                }; // end foreach
            */
            break;
    } // end switch
} // end if
// echo $individual_search;

每个字符串的期望输出:

%foo!bar      => "AND provola LIKE ''foo%'' AND (provola IS NULL OR provola != ''bar'') "
@baz          => "AND provola NOT LIKE ''baz%'' "
!bam@bat@bar  => "AND (provola IS NULL OR provola != ''bam'') AND provola NOT LIKE ''bat%'' AND provola NOT LIKE ''bar%'' "
%bee@baa      => "AND provola LIKE ''bee%'' AND provola NOT LIKE ''baa%'' "

您不得直接向查询中注入值。您需要将脚本设置为使用带有占位符和绑定参数的准备好的语句。

匹配子字符串的两部分并填充必要的数组。

代码:(Demo)

$strings = [
    '%foo!bar',
    '@baz',
    '!bam@bat@bar',
    '%bee@baa',
];
$field = 'your_column';
$conditionTemplates = [
    '&' => '%1$s = ?',
    '!' => '(%1$s IS NULL OR %1$s != ?)',
    '%' => '%1$s LIKE ?',
    '@' => '%1$s NOT LIKE ?',
];
$needsTrailingWildcard = ['%', '@'];

foreach ($strings as $string) {
    $conditions = [];  // reset for demo
    $params = [];  // reset for demo
    preg_match_all('~([&%@!])([^&%@!]+)~', $string, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
        $conditions[] = sprintf($conditionTemplates[$match[1]], $field);
        $params[] = $match[2] . (in_array($match[1], $needsTrailingWildcard) ? '%' : '');
    }
    var_export([implode(' AND ', $conditions), $params]);
    echo "\n";
}

输出:

array (
  0 => 'your_column LIKE ? AND (your_column IS NULL OR your_column != ?)',
  1 => 
  array (
    0 => 'foo%',
    1 => 'bar',
  ),
)
array (
  0 => 'your_column NOT LIKE ?',
  1 => 
  array (
    0 => 'baz%',
  ),
)
array (
  0 => '(your_column IS NULL OR your_column != ?) AND your_column NOT LIKE ? AND your_column NOT LIKE ?',
  1 => 
  array (
    0 => 'bam',
    1 => 'bat%',
    2 => 'bar%',
  ),
)
array (
  0 => 'your_column LIKE ? AND your_column NOT LIKE ?',
  1 => 
  array (
    0 => 'bee%',
    1 => 'baa%',
  ),
)

现在您有了一个 AND 分隔的条件字符串和一个参数数组,您可以遵循类似这样的建议: