本文目录导读:

我来详细讲解一下 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
注意事项
-
安全考虑:
- 防止直接访问PHP文件
- 对上传目录执行权限限制
- 防止路径遍历攻击
-
缓存更新:
- 使用版本号管理静态资源
- 部署时更新版本号
- 配合 CDN 时注意缓存刷新
-
日志记录:
- 静态资源不走访问日志(减少IO)
- 动态请求记录详细日志
- 使用日志切割防止磁盘满
-
调试建议:
# 查看 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 压力。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播