在cakephp 2.5中设置缓存对象时,在控制器中强制重定向

在cakephp 2.5中设置缓存对象时,在控制器中强制重定向,php,cakephp,caching,redirect,memcached,Php,Cakephp,Caching,Redirect,Memcached,我的CakePHP 2.5项目中有一个Categories控制器,它查询外部第三方API以获得类别列表的结果。一旦有了这个结果集,我就将对象缓存在Memcache中,然后使用这个缓存的对象为视图设置变量来呈现页面 这一切都很好,但是一旦设置了缓存,我就不得不执行$This->redirect方法,因为否则在呈现view.ctp时,我的视图变量是空的。如果缓存对象已经存在,那么我不需要重定向,因为变量会立即设置 由于我的整个应用程序都依赖于这个第三方API,所以我在Memcache中进行了大量缓存

我的CakePHP 2.5项目中有一个Categories控制器,它查询外部第三方API以获得类别列表的结果。一旦有了这个结果集,我就将对象缓存在Memcache中,然后使用这个缓存的对象为视图设置变量来呈现页面

这一切都很好,但是一旦设置了缓存,我就不得不执行$This->redirect方法,因为否则在呈现view.ctp时,我的视图变量是空的。如果缓存对象已经存在,那么我不需要重定向,因为变量会立即设置

由于我的整个应用程序都依赖于这个第三方API,所以我在Memcache中进行了大量缓存,在大多数情况下,应用程序在这个重定向中表现正常。然而,当CakePHP无法在Memcache中设置缓存对象时,我遇到了一个重定向循环问题,因为它只是在每个重定向上以相同的方式运行代码结果

下面是一些代码,您可以更好地了解发生了什么

在我的类别控制器中,我有以下视图方法:

public function view($cid, $loc, $page)
{
    $catCache = Cache::read('search_view_'.$cid.'_'.$loc.'_'.$page);
    if (!$catCache) {
        $url = Router::url(
            array(
                'controller' => 'Categories',
                'action' => 'saveCats',
                $page
            )
        );
        $this->requestAction($url);
        $this->redirect();
    }
    $this->set('view', $catCache);
}
这将检查Memcache对象是否已经存在,如果不存在,我将对名为saveCats的API方法执行$This->requestAction,该方法将为我创建缓存对象。执行此操作后,我必须调用重定向,否则$view变量数据为空。这就是saveCats方法的外观:

public function saveCats($page = null)
{
    if (is_null($page)) $page = 0;

    $cid = $this->request->data['Cat']['category'];
    $loc = $this->request->data['Cat']['region'];

    $address  = "http://api.url.com/".$cid;
    $options = array(
        CURLOPT_POST => false,
        CURLOPT_URL => $address,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HTTPAUTH => CURLAUTH_DIGEST,
        CURLOPT_USERPWD => 'username:password'
    );

    $ch = curl_init();
    curl_setopt_array($ch, $options); 
    $content = curl_exec($ch);

    $doc = new DOMDocument(); 
    $filename = $content;
    $doc->loadXML($filename);

    $i = 0;
    while (is_object($view = $doc->getElementsByTagName('category')->item($i))) {
        foreach ($view->childNodes as $nodename) {
            if ($nodename->nodeName=='category:title') {
                $this->request->data['Browse'][$i]['title'] = h($nodename->nodeValue);
            }
            if ($nodename->nodeName=='category:description') {
                $this->request->data['Browse'][$i]['description'] = h($nodename->nodeValue);
            }
        }
        $i++;
    }

    Cache::write('search_view_'.$cid.'_'.$loc.'_'.$page, $this->request->data['Browse'], '2 hours');
    curl_close($ch);
}
最后,为了清楚起见,这里是呈现内容的view.ctp文件

<table border="0" cellspacing="0" cellpadding="0" summary="cat_table">
    <tbody>
    <?php foreach ($view as $cat): ?>
        <tr>
            <td><?php echo h($cat['title']; ?></td>
        </tr>
        <tr>
            <td><?php echo h($cat['description']; ?></td>
        </tr>
    <?php endforeach; ?>
    </tbody>
</table>
我这里主要有两个核心问题。首先,我无法理解我做错了什么,这迫使我必须使用$this->redirect,以便CakePHP正确设置$view变量

我遇到的第二个问题是重定向循环问题,如果不强制执行此重定向,我完全可以避免这个问题。我读过一些关于使用JavaScript可能克服这一问题的方法,但是对于这个项目,我使用绝对零JavaScript,因为它针对的是不支持JavaScript的设备


非常感谢您在上述两个问题上提供的任何帮助。

多亏了一位朋友,我才发现哪里出了问题

为了避免重定向,进而创建无限循环,您需要在设置缓存后再次读取缓存,因为请求操作将设置memcache,但不会读回catCache变量

public function view($cid, $loc, $page)
{
    $catCache = Cache::read('search_view_'.$cid.'_'.$loc.'_'.$page);
    if (!$catCache) {
        $url = Router::url(
            array(
                'controller' => 'Categories',
                'action' => 'saveCats',
                $page
            )
        );
        $this->requestAction($url);
        // Read the cache once the request action has been called
        $catCache = Cache::read('search_view_'.$cid.'_'.$loc.'_'.$page);
        // No need for the redirect now.
        // $this->redirect();
    }
    $this->set('view', $catCache);
}