Принудительно перенаправлять в контроллер при настройке объекта кеша в cakephp 2.5

У меня есть контроллер категорий в моем проекте CakePHP 2.5, который запрашивает внешний сторонний 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, и если нет, я делаю $this->requestAction() на метод API называется saveCats это создает кешированный объект для меня. После того, как это действие было выполнено, я должен вызвать редирект, в противном случае $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.

Любая помощь по вышеупомянутым двум вопросам очень ценится.

0

Решение

Благодаря другу я обнаружил, где все идет не так.

Чтобы избежать необходимости перенаправления и, в свою очередь, создания бесконечного цикла, вам необходимо снова прочитать кэш после того, как он был установлен, потому что действие запроса установит 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);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]