PHP 静态资源怎么托管

wen PHP项目 5

本文目录导读:

PHP 静态资源怎么托管

  1. 本地开发 / 传统部署(Apache / Nginx)
  2. 使用 PHP 内置服务器(开发环境)
  3. 使用 PHP 框架的路由实现静态文件托管
  4. 外部 CDN 托管(生产环境推荐)
  5. 安全与性能优化建议
  6. Docker 容器化部署

在 PHP 中托管静态资源(如图片、CSS、JS、字体等),主要有以下几种方案,具体取决于你的项目类型和部署环境。


本地开发 / 传统部署(Apache / Nginx)

✅ 最佳实践:使用 Web 服务器直出静态文件

不通过 PHP 处理静态文件,而是让 Web 服务器(Nginx/Apache)直接返回静态文件。

Nginx 配置(推荐)

server {
    listen 80;
    server_name example.com;
    root /var/www/html/public;
    # PHP 请求转发给 PHP-FPM
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    # 静态文件直接返回,不经过 PHP
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        try_files $uri =404;
    }
}

Apache 配置(.htaccess)

<IfModule mod_rewrite.c>
    RewriteEngine On
    # 如果是真实存在的静态文件,直接返回
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    # 否则转发给 PHP 入口文件
    RewriteRule ^ index.php [L]
</IfModule>

使用 PHP 内置服务器(开发环境)

# 启动内置服务器,将静态文件放在 public 目录下
php -S localhost:8000 -t public
# 或者用路由文件(需要在 public 目录下创建 router.php)
php -S localhost:8000 public/router.php

router.php 示例:

<?php
// 获取请求的文件路径
$path = __DIR__ . '/' . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// 如果是真实存在的文件,直接返回(不走 PHP 框架)
if (is_file($path)) {
    return false;
}
// 否则走入口文件
require __DIR__ . '/index.php';

使用 PHP 框架的路由实现静态文件托管

Laravel

// routes/web.php
Route::get('/static/{file}', function ($file) {
    $path = storage_path('app/public/' . $file);
    if (file_exists($path)) {
        return response()->file($path);
    }
    abort(404);
})->where('file', '.*');

Symfony

// 使用 Symfony 的文件监听器
use Symfony\Component\HttpFoundation\BinaryFileResponse;
Route::get('/static/{file}', function ($file) {
    $path = __DIR__ . '/../storage/' . $file;
    if (file_exists($path)) {
        return new BinaryFileResponse($path);
    }
    abort(404);
})->where('file', '.*');

外部 CDN 托管(生产环境推荐)

使用阿里云OSS / 腾讯云COS + CDN

// 配置静态资源 URL
class StaticConfig {
    public static $cdnBase = 'https://cdn.example.com';
    public static function asset($path) {
        return self::$cdnBase . '/' . ltrim($path, '/');
    }
}
// 使用
echo '<link rel="stylesheet" href="' . StaticConfig::asset('css/app.css') . '">';

使用七牛云 / 又拍云

// 上传后返回 CDN 地址
$qn = new Qiniu\Storage\UploadManager();
$result = $qn->put(token, $key, $fileContent);
$cdnUrl = 'https://cdn.example.com/' . $key;

安全与性能优化建议

安全防护

// 防止目录穿越
$file = base64_decode(request('file'));
$realPath = realpath(storage_path() . '/' . $file);
$allowedPath = realpath(storage_path());
if (!$realPath || strpos($realPath, $allowedPath) !== 0) {
    abort(403);
}

缓存头设置

// 设置长缓存
$response = response()->file($path, [
    'Cache-Control' => 'public, max-age=31536000',
    'Expires' => gmdate('D, d M Y H:i:s T', time() + 31536000),
]);
// 添加 ETag
$etag = md5_file($path);
$response->setEtag($etag);
$response->isNotModified(request());

Docker 容器化部署

# 多阶段构建
FROM composer:2 AS build
WORKDIR /app
COPY . .
RUN composer install --no-dev
FROM php:8.2-fpm AS app
COPY --from=build /app /var/www
# 使用 Nginx 直接服务静态文件,PHP-FPM 只处理 PHP
server {
    listen 80;
    # 静态文件直接由 Nginx 服务
    location /static/ {
        alias /var/www/public/static/;
    }
    location ~ \.php$ {
        fastcgi_pass php-fpm:9000;
    }
}

场景 推荐方案
传统部署 Web 服务器直出(性能最好)
开发环境 PHP 内置服务器 + router.php
小型项目 框架路由托管(注意安全验证)
中大型项目 CDN + 云存储(阿里云OSS等)
容器化部署 Nginx 容器直出静态文件

最重要的原则:不要让 PHP 处理静态文件请求,交给专业的 Web 服务器或 CDN,性能会好得多。

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