Cải thiện hiệu suất trang web là một yếu tố quan trọng trong việc cung cấp trải nghiệm người dùng tốt. Một cách hiệu quả để làm điều này là sử dụng cache. Trong bài viết này, chúng ta sẽ xây dựng một plugin cache cho WordPress, lưu trữ cache vào các tệp. Plugin này sẽ tự động xóa cache khi bài viết được cập nhật hoặc xóa và cung cấp giao diện quản trị để xóa toàn bộ cache.

Cấu Trúc Plugin

Cấu trúc thư mục plugin:

wp-file-cache/
│
├── wp-file-cache.php
└── .gitignore

File cache lưu tại wp-content/uploads/wp-file-cache/

uploads/
└── wp-file-cache/

Mã Nguồn Plugin

Tạo một thư mục mới trong thư mục wp-content/plugins và đặt tên là wp-file-cache. Sau đó, tạo một tệp PHP trong thư mục này với tên wp-file-cache.php và thêm đoạn mã sau:

<?php
/*
Plugin Name: WP File Cache
Description: Plugin chức năng Cache trong WordPress
Version: 1.0
Author: VNEngineer
*/

if (!defined('ABSPATH')) {
    exit; // Exit nếu truy cập trực tiếp
}

class WPFileCachePlugin
{
    private $cache_dir;

    public function __construct()
    {
        // Đặt thư mục để lưu cache
        $upload_dir = wp_upload_dir();
        $this->cache_dir = $upload_dir['basedir'] . '/wp-file-cache/';

        // Tạo thư mục cache nếu chưa tồn tại
        if (!file_exists($this->cache_dir)) {
            mkdir($this->cache_dir, 0755, true);
        }

        // Hook vào WordPress actions
        add_action('init', [$this, 'start_cache']);
        add_action('save_post', [$this, 'clear_cache_on_update']); // Xóa cache khi bài viết được cập nhật
        add_action('delete_post', [$this, 'clear_cache_on_update']); // Xóa cache khi bài viết bị xóa

        // Thêm action để xóa toàn bộ cache
        add_action('admin_post_clear_all_cache', [$this, 'clear_all_cache']);
    }

    // Hàm để bắt đầu quá trình cache
    public function start_cache()
    {
        // Không cache trang admin hoặc khi người dùng đang đăng nhập
        if (is_admin() || is_user_logged_in()) {
            return;
        }

        // Tạo cache key cho các loại trang khác nhau
        if (is_singular()) {
            global $post;
            $cache_key = md5(site_url(get_permalink($post->ID)));
        } elseif (is_category()) {
            $category = get_queried_object();
            $cache_key = md5(site_url(get_category_link($category->term_id)));
        } elseif (is_tag()) {
            $tag = get_queried_object();
            $cache_key = md5(site_url(get_tag_link($tag->term_id)));
        } elseif (is_author()) {
            $author = get_queried_object();
            $cache_key = md5(site_url(get_author_posts_url($author->ID)));
        } else {
            $cache_key = md5(site_url($_SERVER['REQUEST_URI']));
        }

        $cache_file = $this->cache_dir . $cache_key . '.html';

        // Nếu cache file tồn tại và chưa hết hạn, đọc file và hiển thị nội dung cache
        if (file_exists($cache_file) && time() - filemtime($cache_file) < 3600) {
            echo file_get_contents($cache_file);
            exit; // Dừng thực thi thêm code WordPress
        }

        // Nếu không có cache hoặc cache đã hết hạn, bắt đầu ghi output vào buffer
        ob_start([$this, 'save_cache']);
    }

    // Hàm lưu cache
    public function save_cache($content)
    {
        // Tạo cache key dựa trên loại trang hiện tại
        if (is_singular()) {
            global $post;
            $cache_key = md5(site_url(get_permalink($post->ID)));
        } elseif (is_category()) {
            $category = get_queried_object();
            $cache_key = md5(site_url(get_category_link($category->term_id)));
        } elseif (is_tag()) {
            $tag = get_queried_object();
            $cache_key = md5(site_url(get_tag_link($tag->term_id)));
        } elseif (is_author()) {
            $author = get_queried_object();
            $cache_key = md5(site_url(get_author_posts_url($author->ID)));
        } else {
            $cache_key = md5(site_url($_SERVER['REQUEST_URI']));
        }

        $cache_file = $this->cache_dir . $cache_key . '.html';

        // Lưu nội dung trang vào file cache
        file_put_contents($cache_file, $content);

        // Trả về nội dung trang
        return $content;
    }

    // Hàm để xóa cache khi bài viết hoặc trang được cập nhật hoặc xóa
    public function clear_cache_on_update($post_id)
    {
        // Lấy URL của bài viết bị thay đổi
        $post_url = get_permalink($post_id);

        if ($post_url) {
            // Tạo cache key dựa trên URL của bài viết
            $post_cache_key = md5(site_url($post_url));
            $post_cache_file = $this->cache_dir . $post_cache_key . '.html';

            // Xóa file cache của bài viết này
            if (file_exists($post_cache_file)) {
                unlink($post_cache_file);
            }

            // Xóa cache của các trang chuyên mục và thẻ tag liên quan
            $post_categories = wp_get_post_categories($post_id);
            foreach ($post_categories as $category_id) {
                $category_cache_key = md5(site_url(get_category_link($category_id)));
                $category_cache_file = $this->cache_dir . $category_cache_key . '.html';
                if (file_exists($category_cache_file)) {
                    unlink($category_cache_file);
                }
            }

            $post_tags = wp_get_post_tags($post_id);
            foreach ($post_tags as $tag) {
                $tag_cache_key = md5(site_url(get_tag_link($tag->term_id)));
                $tag_cache_file = $this->cache_dir . $tag_cache_key . '.html';
                if (file_exists($tag_cache_file)) {
                    unlink($tag_cache_file);
                }
            }

            // Xóa cache của trang tác giả liên quan
            $post_author_id = get_post_field('post_author', $post_id);
            if ($post_author_id) {
                $author_cache_key = md5(site_url(get_author_posts_url($post_author_id)));
                $author_cache_file = $this->cache_dir . $author_cache_key . '.html';
                if (file_exists($author_cache_file)) {
                    unlink($author_cache_file);
                }
            }
        }
    }

    // Hàm để xóa toàn bộ cache
    public function clear_all_cache()
    {
        // Quét toàn bộ thư mục cache và xóa tất cả file
        $files = glob($this->cache_dir . '*.html'); // Tìm tất cả các file .html trong thư mục cache

        foreach ($files as $file) {
            if (file_exists($file)) {
                unlink($file); // Xóa từng file
            }
        }

        // Thêm thông báo thành công khi xóa cache
        wp_redirect(admin_url('admin.php?page=clear_cache&status=success'));
        exit;
    }
}

// Khởi tạo plugin
new WPFileCachePlugin();

// Thêm menu và trang quản trị để xóa toàn bộ cache
add_action('admin_menu', 'wp_file_cache_menu');

function wp_file_cache_menu()
{
    add_menu_page(
        'Clear Cache', // Tiêu đề trang
        'Clear Cache', // Tên menu
        'manage_options', // Quyền truy cập
        'clear_cache', // Slug trang
        'wp_file_cache_page', // Callback để hiển thị nội dung trang
        'dashicons-trash', // Icon của menu
        99 // Vị trí menu
    );
}

function wp_file_cache_page()
{
    if (isset($_GET['status']) && $_GET['status'] === 'success') {
        echo '<div class="notice notice-success"><p>Cache cleared successfully!</p></div>';
    }

    echo '<div class="wrap">';
    echo '<h1>Clear Cache</h1>';
    echo '<a href="' . admin_url('admin-post.php?action=clear_all_cache') . '" class="button button-primary">Clear All Cache</a>';
    echo '</div>';
}

Giải Thích Mã Nguồn

  1. Khởi Tạo Plugin
    • __construct: Tạo thư mục cache nếu chưa tồn tại và thêm các hook vào các action của WordPress để bắt đầu cache và xóa cache khi cần.
  2. Bắt Đầu Cache
    • start_cache: Nếu không phải trang admin và người dùng chưa đăng nhập, tạo một cache key dựa trên loại trang hiện tại. Nếu cache đã tồn tại và còn hiệu lực, hiển thị nội dung cache và dừng thực thi thêm. Nếu không, bắt đầu lưu nội dung vào buffer.
  3. Lưu Cache
    • save_cache: Lưu nội dung trang vào tệp cache dựa trên cache key.
  4. Xóa Cache
    • clear_cache_on_update: Xóa cache liên quan đến bài viết khi bài viết được cập nhật hoặc xóa, bao gồm cache của các trang danh mục, thẻ tag, và trang tác giả.
  5. Xóa Toàn Bộ Cache
    • clear_all_cache: Xóa tất cả các tệp cache trong thư mục cache và thêm thông báo thành công khi hoàn tất.
  6. Giao Diện Quản Trị
    • wp_file_cache_menu: Thêm menu và trang quản trị để xóa toàn bộ cache.
    • wp_file_cache_page: Hiển thị giao diện để xóa toàn bộ cache từ trang quản trị.

Kết Luận

Plugin WP File Cache là một công cụ đơn giản và hiệu quả để cải thiện hiệu suất trang web WordPress của bạn bằng cách lưu trữ cache vào các tệp. Bằng cách sử dụng các phương pháp cache và xóa cache linh hoạt, bạn có thể tối ưu hóa tốc độ tải trang và giảm tải cho máy chủ. Nếu có bất kỳ câu hỏi hoặc cần hỗ trợ thêm, hãy liên hệ với chúng tôi!

Qua bài viết này, bạn đã nắm được những bước cơ bản để tự tay viết một plugin cache cho website WordPress của mình. Việc tự tạo một plugin không chỉ giúp bạn tối ưu hiệu suất trang web mà còn giúp bạn hiểu rõ hơn về cách hệ thống cache hoạt động. Từ đó, bạn có thể tùy chỉnh và mở rộng theo nhu cầu thực tế của mình, thay vì phụ thuộc vào các plugin có sẵn. Việc kiểm soát toàn bộ quy trình caching sẽ giúp bạn nâng cao khả năng quản lý tài nguyên, tăng tốc độ tải trang và cải thiện trải nghiệm người dùng. Hãy tiếp tục khám phá và phát triển những tính năng mới, đưa trang web của bạn lên một tầm cao mới!