2012-04-19 3 views
1

현재 Zend_Cache_Backend_Static을 사용하여 페이지를 정적 HTML 파일에 캐시하는 앱을 실행하고 있습니다. 잘못된 URL을 요청하면 캐시가 수백 개의 빈 파일과 폴더로 채워지는 것을 제외하고는 실제로 잘 작동합니다. 예외가 발생하면 캐시되는 페이지를 방지 할 수있는 방법이 있습니까? 나는 이것이 표준적인 행동이 아니라는 사실에 놀랐다. 나는 조금 파고 실제로 정적 HTML 페이지를 저장 처리하는 ZF 코드를 한 적이Zend_Cache_Backend_Static을 사용할 때 오류 페이지 캐싱 방지

는 Zend_Cache_Frontend_Capture에 다음과 같습니다

public function _flush($data) {   
    $id = array_pop($this->_idStack); 
    if ($id === null) { 
     Zend_Cache::throwException('use of _flush() without a start()'); 
    } 
    if ($this->_extension) { 
     $this->save(serialize(array($data, $this->_extension)), $id, $this->_tags); 
    } else { 
     $this->save($data, $id, $this->_tags); 
    } 
    return $data; 
} 

이 기능을위한 ob_start에 대한 output_callback을합니다. 나는 상태를 테스트하기 위해 응답 객체를 유지하려고 시도했지만 _flush 내에서 작동하지 않는 것 같습니다.

$response = Zend_Controller_Front::getInstance()->getResponse(); 

if($response->getStatus() == '200') { 
    // do the save as normal 
} 
else { 
    // do nothing 
    return false; 
} 

내 유일한 생각은 ($ 데이터) 나 strlen 경우에만 0이 작동하는 것 같다 그러나 충분히 강력한 느끼지 않는다> 캐시, $의 데이터 길이를 테스트하는 것이었다.

업데이트 :

불행하게도 우리는 정적 페이지가 이미 그 시점에서 캐시가 작동하지 않습니다 해제, 캐시에 기록 된 ErrorController 충돌 시간에 의해. 그러나 $ _SERVER [ 'REQUEST_URI']에 기반한 페이지를 제거하는 것이 가능합니다. 이것은 페이지가 처음 쓰여질 때 id로 사용되는 것입니다.

$this->_helper->cache->removePage($_SERVER['REQUEST_URI'], true); 

그것은 잘 작동하지만, 나는 처음에 페이지를 작성하지 않으려는 것 :이 줄은 ErrorController에 errorAction의 시작에 추가 할 수 있습니다!

답변

-1

표준 ErrorController을 사용하여 404, 500 및 처리되지 않은 예외를 처리하고 거기에서 캐시 개체에 대한 참조를 가져올 수 있으면 오류 처리기에서 캐싱을 해제 할 수 있습니다. 당신의 오류 컨트롤러에서

(또는에서 캐싱을 취소하고 싶은 곳), 시도 :

$cache->setOption('caching', false); 

Zend_Cache_Coresave() metod이 Zend_Cache_Frontend_Capture::_flush()에 의해 호출되면, 그것은 caching 옵션이 false로 설정되어 표시됩니다 실제로 데이터를 캐시에 저장하지 않고 true를 반환합니다. 추가 실험에서

+0

ErrorController에 도달 할 때까지 정적 페이지가 이미 작성되었으므로 아무 효과가 없습니다. – baseten

+0

그럴 경우,'routeShutdown()'에서 실행되는 플러그인이 캐시를 비활성화 할 수있을만큼 빠를 수 있지만 그 당시에는 페이지가 404임을 알아야합니다. – drew010

+0

좋은 생각입니다. 나는 그것을 줄 것이다 ... – baseten

2

문제는 404 (예. Zend_Controller_Plugin_ErrorHandler :: EXCEPTION_NO_ROUTE, Zend_Controller_Plugin_ErrorHandler :: EXCEPTION_NO_CONTROLLER, Zend_Controller_Plugin_ErrorHandler :: EXCEPTION_NO_ACTION)을 일으킬 표준 젠드 프레임 워크 예외로하지만 내 사용자 정의 예외 다운되지 않습니다. Zend_Cache_Backend_Static이 액션 컨트롤러의 init 메소드에서 초기화 될 필요가 있기 때문에 지금 생각해 보면 분명합니다. 경로, 컨트롤러 또는 동작이없는 상황에서는 어쨌든 초기화되지 않습니다.

사용자가 존재하지 않는 기사를 쿼리하는 기존 작업에 예외가 발생합니다. 그러므로 캐싱은 init에서 가능하며 프론트 컨트롤러 플러그인에서 postDispatch를 누르는 시점까지 페이지가 작성되었습니다 (아직 왜 그런지는 확실하지 않습니다). 그래서 그 시점에서 취소 할 수 없습니다. 한 가지 해결책은 예외를 throw 할 시점에서 캐시를 취소하는 것입니다. 정적 페이지 캐싱을 관리하는 표준 방법은 Zend_Controller_Action_Helper_Cache 액션 도우미를 사용하는 것입니다.나는이 그렇게 같이 취소 메소드를 추가 확장했습니다

<?php 

class Zend_Controller_Action_Helper_PageCache extends Zend_Controller_Action_Helper_Cache { 

    public function cancel() { 
     $cache = $this->getCache(Zend_Cache_Manager::PAGECACHE); 
     $cache->setOption('caching', false); 
     $cache->getBackend('disable_caching', true); 
    } 
} 

내 액션 컨트롤러는 이제 다음과 같습니다

<?php 

class IndexController extends Zend_Controller_Action { 

    private $_model; 

    public function init() {   
     $this->_model = new Model(); 

     // using extended pageCache rather than $this->_helper->cache: 
     $this->_helper->pageCache(array('index'), array('indexaction')); 
    } 

    public function indexAction() { 
     $alias = $this->_request->getParam('article'); 
     $article = $this->_model->getArticleByAlias($alias); 

     if(!$article) { 
      // new cancel method will disable caching 
      $this->_helper->pageCache->cancel(); 
      throw new Zend_Controller_Action_Exception('Invalid article alias', 404); 
     } 

     $this->view->article = $article; 
    } 
} 
0

당신은 옵션 filesizes를 확인하기 위해 귀하의 .htaccess 파일의 RewriteRules을 변경해야합니다 - 의

페이지가 캐시 될 때 오류가 (따라서 0 바이트 파일을 생성) 발생할 경우이 방법이 영구적으로 캐시에 저장되지 않습니다.