web-dev-qa-db-fra.com

Les noms d'options longues échouent silencieusement?

Cela me rendait vraiment fou. Je déboguais du code avec des noms transitoires générés par le code et ils échouaient comme des fous sans raison apparente.

Après beaucoup de douleur et d’expérimentation, j’ai compris qu’il échouait lorsque la longueur de clé était dépassée:

$key = '1234567890';
var_dump( get_transient($key) ); // works just fine
var_dump( set_transient( $key, $key, 10) ); // false when not expired


$key = '1234567890123456789012345678901234567890123456';
var_dump( get_transient($key) ); // always returns false
var_dump( set_transient( $key, $key, 10) ); // always true

Apparemment, le champ option_name dans la base de données est varchar(64).

Cependant, je ne peux absolument pas comprendre pourquoi cela ne produit pas d'erreurs dans la base de données, ni tous les retours et accrochages lors de la configuration du travail transitoire sont corrects ... Sauf qu'en réalité, l'option de délai d'attente n'est pas écrite et tout échoue lamentablement.

Je soupçonne cette requête dans add_option():

$result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $value, $autoload ) );

Quelqu'un peut-il nous aider à déterminer ce qu'il convient de faire lorsque le nom de l'option est transmis trop long et pourquoi il ne génère pas d'erreur ou quoi que ce soit?

2
Rarst

Vous ne recevez pas d'erreur car WordPress ne vérifie pas la longueur , et MySQL la tronque silencieusement (en donnant un avertissement, pas une erreur), sauf si vous activez l'option STRICT_ALL_TABLES (qui transformera l'avertissement en erreur).

Encore plus déroutant, lorsque vous activez le multisite , les options sont enregistrées dans la table sitemeta avec une longueur de clé maximale de 255, mais sans multisite, elles passent à options où la longueur maximale de la clé est de 64. Amusez-vous à déboguer cela dans votre plugin!

9
Jan Fabry

Je me suis heurté à ce problème et j'ai proposé de rallonger la colonne:

http://core.trac.wordpress.org/ticket/13310

6
scribu

Comportement très étrange. J'imagine que l'option est en cours d'ajout, mais que son nom est tronqué à 64 caractères? De cette façon, $wpdb->rows_affected renvoie 1, comme il se doit pour que cette vérification soit réussie à la fin de update_option :

$wpdb->update($wpdb->options, array('option_value' => $newvalue), array('option_name' => $option_name) );

if ( $wpdb->rows_affected == 1 ) {
   do_action( "update_option_{$option_name}", $oldvalue, $_newvalue );
   do_action( 'updated_option', $option_name, $oldvalue, $_newvalue );
   return true;
}

Mais l'option n'est pas accessible via get_option car le champ nom_option n'est pas égal à $ key.

L'extension de la longueur de la colonne est une solution, mais il semble qu'il devrait y avoir une vérification supplémentaire à la fin de update_option que la ligne affectée correspond à la clé fournie. Et peut-être la même chose avec d'autres fonctions de mise à jour comme update_post_meta , bien que la limite de 255 caractères y soit beaucoup plus raisonnable.

2
goldenapples

Vous pouvez mettre à jour la table et augmenter la taille des lignes?