1

現在、Zend_Cache_Backend_Static を使用してページを静的な html ファイルにキャッシュするアプリを実行しています。これは非常にうまく機能しますが、間違った URL が要求されたときにキャッシュが何百もの空のファイルとフォルダーでいっぱいになることを除けば. 例外がスローされている場合にページがキャッシュされないようにする方法はありますか? これが標準的な動作ではないことを発見して驚きました。

少し掘り下げてみましたが、実際に静的 html ページの保存を処理する ZF コードは、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;
}

私の他の唯一の考えは、 $data の長さをテストすることでした。 strlen($data) > 0 の場合にのみキャッシングが機能しているように見えますが、十分に堅牢ではないと感じています。

アップデート:

残念ながら、ErrorController に到達するまでに、静的ページは既にキャッシュに書き込まれているため、その時点でキャッシュを無効にしても機能しません。ただし、ページが最初に書き込まれたときに ID として使用される $_SERVER['REQUEST_URI'] に基づいてページを削除することは可能です。この行は、ErrorController の errorAction の先頭に追加できます。

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

それはうまく機能しますが、そもそもページを書きたくないのです!

4

3 に答える 3

2

さらなる実験の結果、問題は 404 を引き起こす標準の Zend Framework 例外 (つまり、Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE、Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER、Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION) ではなく、私のカスタム例外です。アクション コントローラの init メソッドで Zend_Cache_Backend_Static を初期化する必要があるため、考えてみればこれは明らかです。ルート、コントローラー、またはアクションがない状況では、とにかく初期化されることはありません。

ユーザーが存在しない記事を照会している可能性がある既存のアクションで例外をスローしています。そのため、init でキャッシュが有効になり、フロント コントローラー プラグインで postDispatch を実行するまでにページが書き込まれているため (なぜそうなのかはまだわかりません)、その時点でキャンセルすることはできません。その場合の 1 つの解決策は、例外がスローされた時点でキャッシュをキャンセルすることです。静的ページ キャッシュを管理する標準的な方法は、 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;
    }
}
于 2012-04-26T14:46:32.080 に答える
0

オプション -s を使用してファイルサイズを確認するには、.htaccess ファイルの RewriteRules を変更する必要があります。

このようにして、ページがキャッシュされているときにエラーが発生した場合 (したがって、0 バイトのファイルが生成されます)、キャッシュに永続的に保存されることはありません。

于 2013-04-12T09:17:08.330 に答える
-1

標準ErrorControllerを使用して 404、500、および未処理の例外を処理していて、そこからキャッシュ オブジェクトへの参照を取得できる場合は、エラー ハンドラからキャッシュを無効にすることができます。

エラーコントローラー(またはキャッシュをキャンセルしたい場所)で、次を試してください:

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

save()メソッドがZend_Cache_Coreによって呼び出されるとZend_Cache_Frontend_Capture::_flush()、オプションが false に設定されていることがわかり、caching実際にはデータがキャッシュに保存されず、true が返されます。

于 2012-04-19T17:58:49.243 に答える