解析符号-字符串对以构建 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
分隔的条件字符串和一个参数数组,您可以遵循类似这样的建议:
我需要 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
分隔的条件字符串和一个参数数组,您可以遵循类似这样的建议: