在cakephp 2.5中设置缓存对象时,在控制器中强制重定向
我的CakePHP 2.5项目中有一个Categories控制器,它查询外部第三方API以获得类别列表的结果。一旦有了这个结果集,我就将对象缓存在Memcache中,然后使用这个缓存的对象为视图设置变量来呈现页面 这一切都很好,但是一旦设置了缓存,我就不得不执行$This->redirect方法,因为否则在呈现view.ctp时,我的视图变量是空的。如果缓存对象已经存在,那么我不需要重定向,因为变量会立即设置 由于我的整个应用程序都依赖于这个第三方API,所以我在Memcache中进行了大量缓存,在大多数情况下,应用程序在这个重定向中表现正常。然而,当CakePHP无法在Memcache中设置缓存对象时,我遇到了一个重定向循环问题,因为它只是在每个重定向上以相同的方式运行代码结果 下面是一些代码,您可以更好地了解发生了什么 在我的类别控制器中,我有以下视图方法:在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中进行了大量缓存
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);
}