J'ai sérialisé les méta-valeurs post. Cela ressemble à ceci:
Dans le tableau:
$kisiArray = array(
'option1' => 7,
'option2' => 'bar',
'option3' => 'Apple',
'option4' => 'orange'
);
Et je veux faire une requête personnalisée avec meta_query args. Voici mes arguments de requête:
<?php
$args = array(
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'themeOps_option1',
'value' => 6,
'compare' => '>=',
)
)
);
?>
Mais cela n’affiche aucun résultat.
Ce n'est pas une bonne idée de sauvegarder un tableau sérialisé dans un meta_value
si vous envisagez d'interroger ultérieurement une valeur quelconque dans ce tableau sérialisé. La meilleure option consiste donc à enregistrer les métadonnées sous forme de paire clé/valeur.
Bien que ce ne soit pas une bonne approche, il est toujours possible d'interroger un tableau sérialisé dans meta_value
à l'aide de expression régulière .
Attention: _ Performance sage ce n'est pas une bonne idée du tout. Donc, si vous avez un autre moyen de réaliser la même chose, mieux le faire. Je ne réponds que pour montrer que c'est possible. Alors utilisez-le seulement en dernier recours .
Exemple CODE:
// 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',
)
)
);
Comme vous pouvez le constater, j’ai utilisé 'compare' => 'REGEXP'
et la fonction wpse311157_serialize_num_greater_equals_regex( 'option1', 6 )
pour générer l’expression régulière appropriée (le premier paramètre est le nom du tableau key
et le deuxième paramètre est le nombre à comparer avec >=
).
Maintenant, implémentons la fonction wpse311157_serialize_num_greater_equals_regex
. Étant donné que meta_value
est un tableau sérialisé, il se présentera comme suit: a:1:{s:3:"key";i:7;}
. Pour correspondre à cela, notre CODE ressemblera à:
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 ) . ');.*\}';
}
Nous devons maintenant implémenter la fonction wpse311157_num_greater_equals_regex( $num )
en convertissant la comparaison >=
en expression régulière. Ceci est pas très efficace , mais c'est la seule option que nous avons.
>=
L'algorithme est simple:
(A) Pour tout numéro de chiffre n
__, tout nombre comportant (n+1)
chiffres est supérieur à ce nombre.
(B) De plus, nous avons besoin du nombre maximal de n
(nombre de règles) pour vérifier les autres nombres de n
name (chiffres) supérieurs ou égaux à ce nombre.
Par exemple, supposons que nous voulions comparer: num >= 12
Donc, RegEx: [1-9][0-9][0-9]+
le satisfera toujours, car il correspondra à 3 chiffres ou plus.
Maintenant, pour faire correspondre les nombres à 2 chiffres qui sont >=
12, nous avons besoin de 2 règles:
1[2-9]
=> cela correspondra aux nombres: 12 à 19[2-9][0-9]
=> cela correspondra aux numéros: 20 à 99Donc, le RegEx final pour num >= 12
est: 1[2-9]|[2-9][0-9]|[1-9][0-9][0-9]+
Avec cet algorithme, créons notre fonction 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 );
}
C'est tout, vous pourrez maintenant comparer une valeur avec >=
dans un tableau sérialisé.