PHPのバージョンを
7.1RCから7.1.26に上げた際に発生。
環境
PHP 7.1.26
CAKEPHP 3.3.4
Redis
現象
初回表示は正常に表示できるが、
再度同じ画面を表示した際、データが存在しない表示となる
- キャッシュ作成後、キャッシュを読み込んだ際にエラーが起こっているように見える
- キャッシュのdurationを1秒に設定やキャッシュを使用しないようにすると正常に動作しているように見える
- クエリキャッシュ以外のRedisキャッシュは正常動作しているように見える
- クエリキャッシュもRedisに正常に書き込まれているように見える(Redisサーバにアクセスし確認)
- Reidsキャッシュは取得できているがデータが存在しないように見える
※クエリキャッシュ
https://book.cakephp.org/3.0/ja/orm/query-builder.html#caching-query-results
$query->cache('recent_articles');
原因
- Redisからデータ取得後、unserialize時に正常に復元できていない
/vendor/cakephp/cakephp/src/Cache/Engine/RedisEngine.php#L161
public function read($key)
{
$key = $this->_key($key);
$value = $this->_Redis->get($key);
if (preg_match('/^[-]?\d+$/', $value)) {
return (int)$value;
}
// Redisから値が取得できた、かつ、文字列判定(問題となっているクエリキャッシュはこの分岐に入る)
if ($value !== false && is_string($value)) {/
// PHP7.1RCの場合、"unserialize($value);"でシリアライズ化されたオブジェクトでも正常に復元できる
// PHP7.1.26の場合、"unserialize($value);"でシリアライズ化されたオブジェクトでも正常に復元できず空配列となる
return unserialize($value);
}
return $value;
}
PHP7.1.0よりunserialize関数の挙動が変更されている
http://php.net/manual/ja/function.unserialize.php
対応
CAKEPHP3.5.17導入によりキャッシュ読み込みに関しては解決。
https://stackoverflow.com/questions/47058146/cakephp-query-results-caching
注意
CAKEPHP3.3.4で生成したクエリキャッシュをCAKEPHP3.5.17で読み込むとエラーとなっていた。