PHP8.2になって対応するmemcached extensionがphp_memcached v3.2.0に変わった関係で、キーに日本語などマルチバイトを使うとA BAD KEY WAS PROVIDED
というエラーが出るようになった。
php_memcachedのソースを調べてみた結果v3.1.5とv3.2.0で下記の点が変わっていた。
static
zend_bool s_memc_valid_key_ascii(zend_string *key)
{
const char *str = ZSTR_VAL(key);
size_t i, len = ZSTR_LEN(key);
for (i = 0; i < len; i++) {
- if (iscntrl(str[i]) || isspace(str[i]))
+ if (!isgraph(str[i]) || isspace(str[i]))
return 0;
}
return 1;
}
また、テストコードにもマルチバイトのキーでエラーになるかどうかのチェックが行われているので、バグではなくこのような仕様になっている。
原因としてはlibmemcachedのほうのkeycheckと挙動をそろえた結果の模様。
対処法
(1) バイナリプロトコルを使う
memcached.default_binary_protocolをonにする
https://www.php.net/manual/ja/memcached.configuration.php#ini.memcached.default-binary-protocol
(2) キーをハッシュ関数に通す
$memcached->set(sha1('日本語キー','testvalue'));
$memcached->get(sha1('日本語キー'));