web-dev-qa-db-ja.com

長いオプション名は黙って失敗しますか?

これは本当に私を夢中にさせました。私はコードで生成された一時的な名前を使っていくつかのコードをデバッグしていました、そして、彼らは明白な理由もなく狂ったように失敗していました。

多くの苦痛と実験の後、私はそれが特定の鍵の長さを超えると失敗することを考え出しました:

$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

どうやらデータベースのoption_nameフィールドはvarchar(64)です。

しかし、なぜこれがデータベースエラーを発生させず、一時的な作業を設定することに対するすべてのリターンとフックがうまく機能しないのか、私は絶対に理解できません。

この問い合わせは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 ) );

渡されたオプションの名前が長すぎる場合にどうすればよいのか、またエラーなどが発生しないのはなぜでしょうか。

2
Rarst

WordPressは長さをチェックしない ので、エラーになることはありません。MySQLは(エラーではなく警告を出して)警告なしにそれを切り捨てます。あなたは STRICT_ALL_TABLESオプション を有効にします(これは警告をエラーに変えます)。

さらに紛らわしいことに、 マルチサイト を有効にすると、オプションは最大キー長255でsitemetaテーブルに保存されますが、マルチサイトなしではoptionsに移動します。最大キー長は64です。プラグインでそれをデバッグして楽しんでください。

9
Jan Fabry

私はこの正確な問題に出くわし、列の長さを延長することを提案しました:

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

6
scribu

とても変な振る舞い私はオプションが追加されていると思いますが、その名前は64文字に切り捨てられますか?このチェックがupdate_optionの最後に合格するように、$wpdb->rows_affectedは1を返します。

$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;
}

しかし、option_nameフィールドが$ keyに等しくないため、get_optionを介してオプションにアクセスすることはできません。

列の長さを拡張することは1つの解決策ですが、update_optionの最後に、影響を受ける行が提供されたキーと一致することを確認する必要があるようです。そして、おそらくupdate_post_metaのような他の更新関数でも同じですが、255文字の制限があるほうがはるかに妥当です。

2
goldenapples

あなたはテーブルを更新し、行サイズを増やすことができますか?