本文目录导读:

- 第一步:确定资源存放策略(三种主流方式)
- 第二步:配置CDN回源(最常用,无需移动文件)
- 第三步:修改PHP项目中的资源路径
- 第四步:版本控制(解决缓存问题)
- 第五步:解决混合内容问题 (HTTPS + HTTP)
- 总结配置清单
- 常见问题排查
为PHP项目配置CDN加速静态资源,核心思路是将项目中不经常变化的文件(如CSS、JS、图片、字体等)托管到CDN节点上,并修改项目中的资源引用路径。
以下是标准的配置流程,分为配置、整合和代码实现三个部分:
第一步:确定资源存放策略(三种主流方式)
| 方式 | 描述 | 适合场景 |
|---|---|---|
| CDN回源 | 用户请求CDN -> CDN没有缓存 -> CDN去服务器拉取(回源) | 已有项目,不想改变资源存放位置,配置最简 |
| 上传CDN对象存储 | 将静态资源上传至OSS/S3,CDN从此存储拉取 | 高并发、追求极致性能、不想占用服务器带宽 |
| 全站与静态分离 | 资源放在单独域名下(如 static.example.com) |
浏览器并发请求数限制最佳实践 |
第二步:配置CDN回源(最常用,无需移动文件)
假设你的服务器地址是 www.example.com,域名已经备案。
- 购买CDN服务:阿里云、腾讯云、Cloudflare 等。
- 添加加速域名:
- 域名:
cdn.example.com(或static.example.com) - 源站IP/源站域名:
www.example.com
- 域名:
- CNAME解析:在域名DNS解析处,将
cdn.example.com指向CDN提供的CNAME地址。 - 设置缓存规则:
*.jpg*.png*.gif*.ico:缓存 30天 或 1年*.css*.js:缓存 7天 或 30天*.html:一般不缓存或缓存很短时间(因为HTML可能动态生成)
第三步:修改PHP项目中的资源路径
这是代码层面的核心工作,需保证CDN域名与资源版本控制同步。
方案A:定义全局常量(推荐)
在项目的入口文件或配置文件中定义CDN域名:
// config.php
define('CDN_DOMAIN', 'https://cdn.example.com');
define('STATIC_VERSION', '1.2.0'); // 用于强制刷新CDN缓存
方案B:辅助函数
在模板函数或全局函数库中加入:
// functions.php
/**
* 生成带CDN和版本号的静态资源URL
* @param string $path 相对于项目根目录的路径,如 'assets/css/style.css'
* @return string
*/
function cdn_asset($path) {
$cdn = defined('CDN_DOMAIN') ? CDN_DOMAIN : '';
$version = defined('STATIC_VERSION') ? '?v=' . STATIC_VERSION : '';
// 确保路径开头没有多余的斜杠
$path = ltrim($path, '/');
return $cdn . '/' . $path . $version;
}
方案C:在模板中使用
原生PHP模板:
<link rel="stylesheet" href="<?php echo cdn_asset('assets/css/app.css'); ?>">
<script src="<?php echo cdn_asset('assets/js/main.js'); ?>"></script>
<img src="<?php echo cdn_asset('uploads/logo.png'); ?>" alt="Logo">
Laravel (Blade模板):
// 同样可以在config/app.php 或 .env 中定义 CDN_URL
// .env: CDN_URL=https://cdn.example.com
// 在AppServiceProvider中注册
// AppServiceProvider.php
use Illuminate\Support\Facades\URL;
public function boot() {
if (env('CDN_URL')) {
URL::asset(env('CDN_URL'));
}
}
// 或者在模板中直接使用辅助函数
{{ asset('assets/css/app.css') }}
// 注:asset()默认使用APP_URL,可自行拓展或使用自定义函数
ThinkPHP / 其他MVC框架:
// 在配置文件中定义资源域名
'view_replace_str' => [
'__STATIC__' => 'https://cdn.example.com/static'
];
第四步:版本控制(解决缓存问题)
CDN缓存一旦生效,更新文件后用户可能仍看到旧文件。
推荐方法:修改资源请求URL中的版本号参数。
// 当发布新版本时,修改 STATIC_VERSION 常量
define('STATIC_VERSION', '2.0.0');
// 输出的HTML变为
// <link rel="stylesheet" href="https://cdn.example.com/assets/css/app.css?v=2.0.0">
注意: 少数CDN会忽略
?v=参数,更彻底的办法是使用文件指纹:
// 自动根据文件修改时间生成版本号
$file_path = __DIR__ . '/public/assets/css/app.css';
$version = file_exists($file_path) ? filemtime($file_path) : time();
echo cdn_asset('assets/css/app.css') . '?v=' . $version;
第五步:解决混合内容问题 (HTTPS + HTTP)
如果项目使用 HTTPS,但CDN资源链接是 HTTP,浏览器会阻止加载。
- 最佳实践:CDN域名也配置 SSL 证书,全部使用
https://。 - PHP代码处理:使用
$_SERVER['REQUEST_SCHEME']或config('app.env')判断协议。
// 自动适配协议
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
define('CDN_DOMAIN', $protocol . '://cdn.example.com');
总结配置清单
- DNS层面:
cdn.example.com-> CNAME记录 -> CDN分配域名。 - 服务器/CDN层面:
- 开启自动刷新目录浏览(不建议)。
- 配置源站。
- PHP代码层面:
- 定义
CDN_DOMAIN和STATIC_VERSION。 - 封装
cdn_asset()函数替换所有静态资源路径。 - .env 或配置文件中可灵活切换环境(开发/生产)。
- 定义
- 构建/部署层面:
- 每次更新代码后,修改版本号。
- 如果需要,手动刷新CDN缓存(阿里云CDN/腾讯云控制台 -> 刷新缓存 -> 输入
https://cdn.example.com/assets/css/app.css)。
常见问题排查
- 资源404:检查CDN配置的回源Host是否正确(应与源站服务器绑定的域名一致)。
- 资源加载慢:检查是否选择了地理位置近的CDN节点,或节点数量过少。
- 更新后用户依然看到旧版:检查版本号是否加上了,或CDN缓存时间设置过长(可先手动刷新)。