PHP 怎么PHP FastCGI 缓存

wen PHP项目 3

本文目录导读:

PHP 怎么PHP FastCGI 缓存

  1. Nginx FastCGI Cache(最常用)
  2. PHP 代码层缓存
  3. PHP + Redis/Memcached 缓存
  4. 综合最佳实践配置
  5. PHP 侧缓存控制
  6. 性能调优建议

在 PHP 中实现 FastCGI 缓存,主要有以下几种常见方案,让我详细说明:

Nginx FastCGI Cache(最常用)

基本配置

# 在 http 块中定义缓存路径
http {
    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:100m 
                     inactive=60m max_size=500m;
    # 缓存配置
    server {
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            # 启用缓存
            fastcgi_cache mycache;
            fastcgi_cache_valid 200 60m;
            fastcgi_cache_valid 404 1m;
            # 跳过带 cookie 的请求
            fastcgi_cache_bypass $cookie_session;
            fastcgi_no_cache $cookie_session;
            # 设置缓存标识
            fastcgi_cache_key "$request_method|$request_uri";
        }
    }
}

高级配置

# 缓存变量定义
map $request_uri $cache_bypass {
    default 0;
    ~*admin 1;  # admin 路径不缓存
    ~*login  1;
}
server {
    location ~ \.php$ {
        # ... 基础配置 ...
        # 动态跳过缓存
        fastcgi_cache_bypass $cache_bypass;
        fastcgi_no_cache $cache_bypass;
        # 带客户端标识
        fastcgi_cache_key "$request_method|$http_host|$request_uri|$http_x_request_id";
        # 缓存 POST 请求
        fastcgi_cache_methods GET HEAD;
        # 自定义缓存过期头
        add_header X-Cache $upstream_cache_status;
    }
}

PHP 代码层缓存

使用 APCu 缓存

<?php
class PageCache {
    private static $prefix = 'page_cache:';
    public static function get($key, $ttl = 60) {
        $full_key = self::$prefix . $key;
        $data = apcu_fetch($full_key, $success);
        if ($success) {
            return $data;
        }
        // 获取页面内容
        $content = self::renderPage();
        // 存入缓存
        apcu_store($full_key, $content, $ttl);
        return $content;
    }
    public static function clear($key = null) {
        if ($key) {
            apcu_delete(self::$prefix . $key);
        } else {
            apcu_clear_cache();
        }
    }
}
// 使用示例
$cache_key = md5($_SERVER['REQUEST_URI']);
$page = PageCache::get($cache_key);
echo $page;
?>

文件缓存

<?php
class FileCache {
    private $cacheDir;
    public function __construct($cacheDir = '/tmp/cache') {
        $this->cacheDir = $cacheDir;
        if (!is_dir($cacheDir)) {
            mkdir($cacheDir, 0755, true);
        }
    }
    public function get($key, $ttl = 3600) {
        $filePath = $this->cacheDir . '/' . md5($key) . '.cache';
        if (file_exists($filePath) && (time() - filemtime($filePath) < $ttl)) {
            return file_get_contents($filePath);
        }
        return null;
    }
    public function set($key, $data, $ttl = 3600) {
        $filePath = $this->cacheDir . '/' . md5($key) . '.cache';
        file_put_contents($filePath, $data);
    }
    public function clear() {
        array_map('unlink', glob($this->cacheDir . '/*.cache'));
    }
}
?>

PHP + Redis/Memcached 缓存

Redis 缓存

<?php
class RedisPageCache {
    private $redis;
    private $ttl;
    public function __construct($ttl = 60) {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
        $this->ttl = $ttl;
    }
    public function start($key = null) {
        if (!$key) {
            $key = $_SERVER['REQUEST_URI'];
        }
        $key = 'cache:' . md5($key);
        $cached = $this->redis->get($key);
        if ($cached) {
            echo $cached;
            return true;
        }
        // 开始输出缓冲
        ob_start();
        $this->currentKey = $key;
        return false;
    }
    public function end() {
        $content = ob_get_clean();
        if ($this->currentKey) {
            $this->redis->setex($this->currentKey, $this->ttl, $content);
        }
        echo $content;
    }
    public function clear($key = null) {
        if ($key) {
            $this->redis->del('cache:' . md5($key));
        } else {
            // 清除所有缓存
            $keys = $this->redis->keys('cache:*');
            if (!empty($keys)) {
                $this->redis->del($keys);
            }
        }
    }
}
// 使用示例
$cache = new RedisPageCache(300); // 缓存5分钟
if (!$cache->start()) { // 缓存未命中时执行
    // 页面内容生成
    echo "页面重要内容";
    $cache->end(); // 保存缓存
}
?>

综合最佳实践配置

# Nginx 配置
http {
    # 缓存配置
    fastcgi_cache_path /var/cache/nginx levels=1:2 
                      keys_zone=FASTCGI_CACHE:100m 
                      inactive=60m max_size=500m 
                      use_temp_path=off;
    # 缓存级别配置
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    # 缓存控制变量
    map $http_cookie $cookie_key {
        default "nocache";
        ~*session "withsession";
    }
    server {
        listen 80;
        location ~ \.php$ {
            # PHP-FPM 配置
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
            # 缓存设置
            fastcgi_cache FASTCGI_CACHE;
            fastcgi_cache_valid 200 301 302 60m;
            fastcgi_cache_valid 404 403 1m;
            # 跳过需要动态处理的内容
            fastcgi_cache_bypass $cookie_key;
            fastcgi_no_cache $cookie_key;
            # 添加缓存标识
            add_header X-Cache-Status $upstream_cache_status;
            add_header Cache-Control "public, max-age=60";
            # 更多高级配置
            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
            # 压缩缓存
            gzip_vary on;
        }
    }
}

PHP 侧缓存控制

<?php
// 设置缓存相关头
header('Cache-Control: public, max-age=60');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60) . ' GMT');
// 支持条件请求
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
    $etag = $_SERVER['HTTP_IF_NONE_MATCH'];
    if ($etag == $current_etag) {
        header('HTTP/1.1 304 Not Modified');
        exit;
    }
}
header('ETag: ' . $current_etag);
// 输出缓冲区
ob_start();
echo "动态内容";
// 最后输出
ob_end_flush();
?>

性能调优建议

Nginx 缓存配置优化

# 高级缓存策略
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500 http_502;
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 5s;
fastcgi_cache_revalidate on;
fastcgi_cache_background_update on;

PHP 缓存注意事项

<?php缓存策略
class CacheManager {
    public static function shouldCache() {
        // 检查是否是 GET 请求
        if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
            return false;
        }
        // 检查是否有登录状态
        if (isset($_SESSION['user_id'])) {
            return false;
        }
        // 检查是否为动态页面
        $uri = $_SERVER['REQUEST_URI'];
        if (preg_match('/\/(admin|login|logout|cart)\b/', $uri)) {
            return false;
        }
        return true;
    }
}
?>

选择哪种方案取决于你的具体需求:

  • Nginx FastCGI Cache:性能最好,适合大多数场景
  • Redis/Memcached:适合分布式、需要动态管理的场景
  • APCu/文件缓存:适合简单、单机部署
  • 组合使用:通常在 CDN + Nginx 缓存 + Redis 多层组合效果最佳

抱歉,评论功能暂时关闭!