PHP 怎么PHP动静分离

wen PHP项目 1

本文目录导读:

PHP 怎么PHP动静分离

  1. 查看 PHP-FPM 是否运行
  2. 测试静态资源访问
  3. 测试动态页面

我来详细讲解一下 PHP 的动静分离方案。

什么是动静分离

动静分离是指将动态请求(PHP 处理)和静态请求(图片、CSS、JS 等)分开处理,让静态资源直接由高性能的 Web 服务器(如 Nginx)处理,动态请求才转发给 PHP-FPM。

核心架构

用户请求 → Nginx
              ├── 静态文件 (.css/.js/.jpg等) → 直接返回
              └── 动态请求 (.php等) → 转发给 PHP-FPM → 返回

配置方案

Nginx 基础配置

server {
    listen 80;
    server_name example.com;
    # 设置根目录
    root /var/www/html;
    index index.php index.html;
    # 静态文件处理规则
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|eot|ttf)$ {
        expires 30d;                    # 设置浏览器缓存
        access_log off;                 # 静态资源不记录访问日志
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }
    # 动态 PHP 请求处理
    location ~ \.php$ {
        # 检查文件是否存在
        try_files $uri =404;
        # 转发给 PHP-FPM
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        # 动态请求不缓存
        add_header Cache-Control "no-cache, must-revalidate";
    }
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

高级优化配置

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php index.html;
    # 1. 静态文件优化配置
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|eot|ttf|webp)$ {
        expires 30d;
        access_log off;
        log_not_found off;
        # 开启 gzip 压缩
        gzip on;
        gzip_types text/css application/javascript image/svg+xml;
        # 开启浏览器缓存
        add_header Cache-Control "public, immutable";
        # 优化图片访问
        location ~* \.(jpg|jpeg|png|gif|webp)$ {
            expires 90d;
            add_header X-Content-Type-Options nosniff;
        }
    }
    # 2. 特定目录直接返回静态文件
    location ^~ /static/ {
        alias /var/www/html/static/;
        expires 180d;
        access_log off;
        add_header Cache-Control "public, immutable";
    }
    # 3. 动态 PHP 请求
    location ~ \.php$ {
        # 检查文件存在
        try_files $uri =404;
        # 动态请求不缓存
        add_header Cache-Control "no-store, must-revalidate";
        add_header X-Frame-Options "SAMEORIGIN";
        # 转发到 PHP-FPM
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        # 超时设置
        fastcgi_connect_timeout 30;
        fastcgi_send_timeout 60;
        fastcgi_read_timeout 60;
    }
    # 4. 图片防盗链(可选)
    location ~* \.(jpg|jpeg|png|gif|webp)$ {
        valid_referers none blocked *.example.com example.com;
        if ($invalid_referer) {
            return 403;
        }
    }
}

分离存储方案

将静态资源放到独立域名或 CDN:

# 静态资源服务器配置
server {
    listen 80;
    server_name static.example.com;
    root /data/static;  # 独立的静态资源目录
    location / {
        expires max;
        add_header Cache-Control "public, immutable";
        access_log off;
        # 开启目录列表(可选)
        autoindex off;
    }
}

动态分离的 PHP 代码实现

模板中使用绝对路径

<!-- 动态页面中引用静态资源 -->
<img src="https://static.example.com/images/logo.png">
<link rel="stylesheet" href="https://static.example.com/css/style.css">
<script src="https://static.example.com/js/main.js"></script>

统一资源管理函数

<?php
class ResourceManager {
    private static $staticDomain = 'https://static.example.com';
    // 生成静态资源 URL
    public static function asset($path) {
        $file = $_SERVER['DOCUMENT_ROOT'] . $path;
        // 添加版本号(基于文件修改时间)
        $version = file_exists($file) ? filemtime($file) : date('Ymd');
        return self::$staticDomain . $path . '?v=' . $version;
    }
    // 检查是否需要更新缓存
    public static function getVersion($path) {
        $file = $_SERVER['DOCUMENT_ROOT'] . $path;
        return file_exists($file) ? filemtime($file) : time();
    }
}
// 使用示例
echo '<link rel="stylesheet" href="' . ResourceManager::asset('/css/style.css') . '">';

上传文件分离

<?php
class UploadManager {
    private $staticServer = 'static.example.com';
    private $uploadDir = '/data/static/uploads/';
    public function upload($file) {
        $targetPath = $this->uploadDir . date('Y/m/d') . '/';
        if (!is_dir($targetPath)) {
            mkdir($targetPath, 0755, true);
        }
        $filename = uniqid() . '.' . pathinfo($file['name'], PATHINFO_EXTENSION);
        if (move_uploaded_file($file['tmp_name'], $targetPath . $filename)) {
            // 返回静态服务器 URL
            return "https://{$this->staticServer}/uploads/" . date('Y/m/d') . "/" . $filename;
        }
        return false;
    }
}

性能优化建议

Nginx 层优化

# 开启 sendfile 加速
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 静态资源缓存配置
open_file_cache max=1000 inactive=5m;
open_file_cache_valid 2m;
open_file_cache_min_uses 1;
open_file_cache_errors on;

浏览器缓存策略

# CSS/JS 缓存策略
location ~* \.(css|js)$ {
    expires 7d;
    add_header Cache-Control "public, must-revalidate";
}
# 图片缓存策略
location ~* \.(jpg|jpeg|png|gif)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

PHP-FPM 优化

; php-fpm.conf
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30

注意事项

  1. 安全考虑

    • 防止直接访问PHP文件
    • 对上传目录执行权限限制
    • 防止路径遍历攻击
  2. 缓存更新

    • 使用版本号管理静态资源
    • 部署时更新版本号
    • 配合 CDN 时注意缓存刷新
  3. 日志记录

    • 静态资源不走访问日志(减少IO)
    • 动态请求记录详细日志
    • 使用日志切割防止磁盘满
  4. 调试建议

    # 查看 Nginx 配置是否正确
    nginx -t

查看 PHP-FPM 是否运行

systemctl status php8.1-fpm

测试静态资源访问

curl -I https://static.example.com/css/style.css

测试动态页面

curl -I https://example.com/index.php


这样配置后,静态请求不会进入 PHP 处理,大幅提升网站性能,减少 PHP-FPM 压力。

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