将序列化数组保存在查询的meta\\u值中不是一个好主意meta_value
如果计划稍后使用该序列化数组中的任何值进行查询。因此,最好的选择是将元数据保存为键/值对。
查询序列化数组虽然不是一种好方法,但仍然可以在meta_value
使用regular expression.
Warning: 就性能而言,这根本不是一个好主意。因此,如果你有其他方法来实现同样的目标,最好这样做。我给出答案只是为了证明这是可能的。所以使用它only as a last resort.
示例代码:
// this array is serialized and saved in meta_value for meta_key \'themeOps\'
$serializedArray = array(
\'option1\' => 7,
\'option2\' => \'bar\',
\'option3\' => \'apple\',
\'option4\' => \'orange\'
);
// this is the WP_Query argument
$args = array(
\'meta_query\' => array(
array(
\'key\' => \'themeOps\',
// this compares if \'option1\' >= 6 within the serialized array in meta_value
\'value\' => wpse311157_serialize_num_greater_equals_regex( \'option1\', 6 ),
\'compare\' => \'REGEXP\',
)
)
);
正如你所看到的,我
\'compare\' => \'REGEXP\'
并使用了该功能
wpse311157_serialize_num_greater_equals_regex( \'option1\', 6 )
生成正确的正则表达式(第一个参数是数组的名称
key
第二个参数是要比较的数字
>=
).
现在,让我们实现wpse311157_serialize_num_greater_equals_regex
作用自从meta_value
是一个序列化数组,它将类似于:a:1:{s:3:"key";i:7;}
. 为了匹配这一点,我们的代码如下所示:
function wpse311157_serialize_num_greater_equals_regex( $key, $num ) {
return \'a\\:[1-9][0-9]*\\:\\{.*\' . preg_quote( serialize( $key ) ) . \'i\\:(\' . wpse311157_num_greater_equals_regex( $num ) . \');.*\\}\';
}
现在我们需要实现
wpse311157_num_greater_equals_regex( $num )
转换函数
>=
比较到正则表达式。这是
not very efficient, 但这是我们唯一的选择。
要比较的RegEx算法>=
算法很简单:
(A) 对于任何n
数字,任何带(n+1)
数字大于该数字。
(B) 此外,我们需要最大n
要检查其他的规则数n
大于或等于此数字的数字。
例如,假设我们要比较:num >= 12
所以,正则表达式:[1-9][0-9][0-9]+
将始终满足它,因为它将匹配3个或更多数字。
现在,要匹配两位数>=
12,我们需要两条规则:
1[2-9]
=> 这将匹配数字:12到19[2-9][0-9]
=> 这将匹配数字:20到99,因此num >= 12
是:1[2-9]|[2-9][0-9]|[1-9][0-9][0-9]+
使用此算法,让我们创建wpse311157_num_greater_equals_regex( $num )
功能:
function wpse311157_num_greater_equals_regex( $num ) {
$digits = wpse311157_num_digits( $num );
$num_i = $num;
$regex = \'\';
for( $i = 1; $i <= $digits; $i++ ) {
$digit = $num_i % 10;
$num_i = (int) ( $num_i / 10 );
$regex_i = \'\';
$need_rule = true;
if( 1 === $i ) {
if( 9 === $digit ) {
$regex_i = \'9\';
}
else {
$regex_i = \'[\' . $digit . \'-9]\';
}
}
else {
// no rule for 9
if( 9 === $digit ) {
$need_rule = false;
}
else if( 8 === $digit ) {
$regex_i = \'9\';
}
else {
$regex_i = \'[\' . ( $digit + 1 ) . \'-9]\';
}
}
if( $need_rule ) {
if( $i < $digits ) {
$regex_i = $num_i . $regex_i;
}
for( $j = 1; $j < $i; $j++ ) {
$regex_i = $regex_i . \'[0-9]\';
}
if( empty( $regex ) ) {
$regex = $regex_i;
}
else {
$regex = $regex . \'|\' . $regex_i;
}
}
}
$regex = $regex . \'|[1-9]\';
for( $i = 1; $i < $digits; $i++ ) {
$regex = $regex . \'[0-9]\';
}
$regex = $regex . \'[0-9]+\';
return $regex;
}
function wpse311157_num_digits( $num ) {
// not considering 0 or negative numbers
if( $num < 1 ) return -1;
return floor( log10( $num ) + 1 );
}
仅此而已,现在您可以将值与>=
在序列化数组中。