【问题标题】:CakePHP Query results cachingCakePHP 查询结果缓存
【发布时间】:2018-04-13 23:09:12
【问题描述】:

最近我把CakePHP 3.2项目移到了虚拟主机上(CentOSphp 7.0/5.6都试过了,OpCache启用了),发现查询结果缓存不起作用。

我为导航菜单使用默认文件缓存引擎。

$mt = TableRegistry::get('MenuItems');
$menu = $mt->find('active')
           ->select([
                      "MenuItems.id",'Nodes.id','title', 'header', 'route', 'link',
                      'parent_id' => 'Nodes.parent_id' ])
           ->orderAsc('Nodes.num')
           ->cache("sitemenu_MenuItems", 'long')
           ->hydrate(false)
           ->toArray();

我在本地 OpenServerIIS7IIS8 服务器和其他 Linux 服务器上没有遇到此代码问题。

那么,发生了什么:

当我第一次运行脚本时,cake 从数据库中获取数据并将缓存写入/src/tmp/cache/long/cake_sitemenu__menu_items。文件像往常一样具有序列化内容。
但是当我刷新页面时,我看到空结果。

错误或调试日志中没有任何内容。

我尝试将缓存键小写,但没有成功。

有什么想法吗?


我添加了测试代码来检查基本缓存本身:

    public function qwe(){
            $data = ['key' => 'value'];
            //Cache::write('test', $data, 'long');
            $result = Cache::read('test', 'long');
            $result[] = 'xxx';
            $this->setJsonResponse($result);
    }

并且此代码返回正确的结果。


到目前为止,我发现Cake\Cache\Egine\FileEngine 类的read() 方法存在一些问题。第 223 行:

$data = unserialize((string)$data);

$data 在调用主机和本地计算机之前具有相同的值。然后unserialize 返回带有空items 字段的ResultSet 对象;


SplFixedArrayunserialize 似乎有些东西

哈,不错:PHP 7.0.15 and PHP 7.1.0 ResultSet Caching #10111

【问题讨论】:

  • 与 IIS8.5 & PHP 7.1.12 相同

标签: php caching cakephp cakephp-3.0


【解决方案1】:

如您所见,在调试过程中,我发现问题是由ResultSet 使用的SplFixedArrayunserialize() 引起的。

之后我找到了this topic: PHP 7.0.15 and PHP 7.1.0 ResultSet Caching #10111

就我而言,我尝试使用 PHP 7.0.247.1.55.6.305.5.38。 5.5 运行良好。

该问题在该主题讨论期间已解决,因此我从 CakePHP 3.5 复制了 ResultSet::serializeunserialize 方法。诀窍是像通常的数组一样序列化数据,而不是SplFixedArray

\Cake\ORM\ResultSet

313:     public function serialize()
314:     {
315:         if (!$this->_useBuffering) {
316:             $msg = 'You cannot serialize an un-buffered ResultSet. Use Query::bufferResults() to get a buffered ResultSet.';
317:             throw new Exception($msg);
318:         }
319: 
320:         while ($this->valid()) {
321:             $this->next();
322:         }
323: 
324:         if ($this->_results instanceof SplFixedArray) {
325:             return serialize($this->_results->toArray());
326:         }
327: 
328:         return serialize($this->_results);
329:     }
330: 

339:     public function unserialize($serialized)
340:     {
341:         $results = (array)(unserialize($serialized) ?: []);
342:         $this->_results = SplFixedArray::fromArray($results);
343:         $this->_useBuffering = true;
344:         $this->_count = $this->_results->count();
345:     }

【讨论】:

    猜你喜欢
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2015-11-04
    • 2019-01-27
    • 2011-06-05
    相关资源
    最近更新 更多