【WordPress プラグイン自作】ページキャッシュのファイルを作成する方法

  • 投稿 : 2016-11-07
・Wordpress本体に、ページキャッシュを作成する機構が用意されている
・ページキャッシュのサンプル

WordPress本体に、ページキャッシュを作成する機構が用意されている

WordPress2.5以前では、wp-config.phpにdefine(‘WP_CACHE’, true)を書いた場合のみ、wp_cache関数を使って保存されたデータは永続的に保存されました。
今ではそのようなことはなく、以下のような永続的キャッシュプラグインを使わない限り、define(‘WP_CACHE’, true)は意味がありません。

WP File Cache の実装では、オブジェクトキャッシュをデータベースの読み出しからディスク/ファイルシステムに移行しています。
File-Based Caching for WordPress はWordPress2.1 – 2.3に見られたファイルベースのオブジェクトキャッシュ機構を再実装しています。
Memcached Object Cache はWordPressに対して永続的オブジェクトキャッシュのバックエンドを提供します。memcachedサーバーとPECLのmemcached拡張が必要です。

WordPressの変な処理 WP_Cache | ネクストベータ代表Blog

関数リファレンス/WP Cache - WordPress Codex 日本語版(インターネットアーカイブ)

上記の記事を読むと

define('WP_CACHE', true);
wp-config.phpに上記を記述すると、/wp-content/advanced-cache.php が読みこむようになっていて、これはページキャッシュ用に用意されていたもののようです。

たしかに、キャッシュプラグインの多くがこれを使ってるんですね。

if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) ) {
// For an advanced caching plugin to use. Uses a static drop-in because you would only want one.
	WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' );
}
実際に、wp-settings.phpをみてみると、そのロジックがあります。
この段階で読まれるので、Wordpressの動作する早い段階で読まれることが予想されます。

ということで、この段階でob_startをつかえば、ページ丸ごとのキャッシュがとれそうです。

ページキャッシュのサンプル

A very simple plugin to make your site run lightning fast with caching.

WordPress.org



ページキャッシュができるプラグインをいろいろ見てみたのですが、これが一番私には分かりよかったです。で、上記のソースから必要最小限のものを切り取って、ページキャッシュのファイルを作成できるかどうかを確認してみました。

・define('WP_CACHE', true);を設定
・advanced-cache.phpとして以下のファイルを設置

<?php 
defined( 'ABSPATH' ) || exit;
ob_start( 'sc_cache' );

function sc_get_url_path() {
    $host = ( isset( $_SERVER['HTTP_HOST'] ) ) ? $_SERVER['HTTP_HOST'] : '';
    return rtrim( $host, '/' ) . $_SERVER['REQUEST_URI'];
}

function sc_cache( $buffer, $flags ) {
    if ( strlen( $buffer ) < 255 ) {
        return $buffer;
    }

    // Don't cache search, 404, or password protected
    if ( is_404() || is_search() || post_password_required() ) {
        return $buffer;
    }

    include_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
    include_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';

    $filesystem = new WP_Filesystem_Direct( new StdClass() );

    // Make sure we can read/write files and that proper folders exist
    if ( ! $filesystem->exists( untrailingslashit( WP_CONTENT_DIR ) . '/cache' ) ) {
        if ( ! $filesystem->mkdir( untrailingslashit( WP_CONTENT_DIR ) . '/cache' ) ) {
            // Can not cache!
            return $buffer;
        }
    }

    if ( ! $filesystem->exists( untrailingslashit( WP_CONTENT_DIR ) . '/cache/test-cache' ) ) {
        if ( ! $filesystem->mkdir( untrailingslashit( WP_CONTENT_DIR ) . '/cache/test-cache' ) ) {
            // Can not cache!
            return $buffer;
        }
    }

    //$buffer = apply_filters( 'sc_pre_cache_buffer', $buffer );

    $url_path = sc_get_url_path();
    $dirs = explode( '/', $url_path );
    $path = untrailingslashit( WP_CONTENT_DIR ) . '/cache/test-cache';

    foreach ( $dirs as $dir ) {
        if ( ! empty( $dir ) ) {
            $path .= '/' . $dir;

            if ( ! $filesystem->exists( $path ) ) {
                if ( ! $filesystem->mkdir( $path ) ) {
                    // Can not cache!
                    return $buffer;
                }
            }
        }
    }

    $modified_time = time(); // Make sure modified time is consistent

    if ( preg_match( '#</html>#i', $buffer ) ) {
        $buffer .= "\n<!-- Cache served by Simple Cache - Last modified: " . gmdate( 'D, d M Y H:i:s', $modified_time ) . " GMT -->\n";
    }

    $filesystem->put_contents( $path . '/index.html', $buffer, FS_CHMOD_FILE );
    $filesystem->touch( $path . '/index.html', $modified_time );

    header( 'Cache-Control: no-cache' ); // Check back every time to see if re-download is necessary    header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $modified_time ) . ' GMT' );

    return $buffer;
}

きちんと動作すれば、/wp-content/cache/test-cache/ディレクトリ以下に、ページキャッシュファイルが作成されるかと思います。


ob_start — 出力のバッファリングを有効にする
PHP: ob_start - Manual

原理自体は簡単で、ob_start でバッファリングをして、それをファイルに出力するという処理になっています。「ob_start( 'sc_cache' );」がそうで、コールバック関数として「sc_cache」を指定しています。



スポンサーリンク