メタ値をシリアル化しました。それはこのように見えます:
配列では:
$kisiArray = array(
'option1' => 7,
'option2' => 'bar',
'option3' => 'Apple',
'option4' => 'orange'
);
そして、 meta_query argsを使ってカスタムクエリを作りたいこれは私のクエリ引数です:
<?php
$args = array(
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'themeOps_option1',
'value' => 6,
'compare' => '>=',
)
)
);
?>
しかし、結果は表示されません。
後でその直列化配列内の任意の値で照会する予定がある場合は、直列化配列をmeta_value
に保存することはお勧めできません。そのため、最善の選択肢は、メタデータをキーと値のペアとして保存することです。
これは良い方法ではありませんが、 正規表現 を使ってmeta_value
内で直列化された配列を問い合わせることは可能です。
警告:パフォーマンスの面でこれはまったく良い考えではありません。あなたが同じことを成し遂げるための他の方法があるならばそれでそれをしなさい。それが可能であることを示すためだけに答えを出しています。それで 最後の手段としてのみ使用してください 。
コード例:
// 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
の名前、2番目のパラメーターは>=
と比較する番号です)。
それでは、wpse311157_serialize_num_greater_equals_regex
関数を実装しましょう。 meta_value
は直列化された配列なので、a:1:{s:3:"key";i:7;}
のようになります。それに合わせるために、私たちのCODEは次のようになります。
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 )
関数を実装する必要があります。これは それほど効率的ではない ですが、これが唯一の選択肢です。
>=
を比較するためのRegExアルゴリズムアルゴリズムは簡単です:
(A)任意のn
桁の番号について、(n+1)
桁の番号はその番号より大きい。
(B)さらに、この数以上の他のn
桁数をチェックするには、最大n
個のルールが必要です。
たとえば、比較したいとします。num >= 12
したがって、RegEx:[1-9][0-9][0-9]+
は、3桁以上の数字に一致するため、常にこれを満たします。
さて、>=
12である2桁の数字と一致させるには、2つの規則が必要です。
1[2-9]
=>これは数字にマッチします:12から19[2-9][0-9]
=>これは数字にマッチします:20から99num >= 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 );
}
以上で、直列化された配列内で>=
と値を比較できるようになりました。