Apache PHP 集成 #

PHP 集成概述 #

集成方式对比 #

text
┌─────────────────────────────────────────────────────────────┐
│                    PHP 集成方式                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  mod_php(Apache 模块)                                     │
│  ├── PHP 作为 Apache 模块运行                               │
│  ├── 配置简单                                               │
│  ├── 性能较好(进程内运行)                                 │
│  ├── 内存占用较高                                           │
│  ├── 需要 Prefork MPM                                       │
│  └── 适合传统 PHP 应用                                      │
│                                                             │
│  PHP-FPM(FastCGI 进程管理器)                              │
│  ├── PHP 作为独立进程运行                                   │
│  ├── 配置灵活                                               │
│  ├── 资源管理更好                                           │
│  ├── 支持 Event MPM                                         │
│  ├── 可与 Nginx 配合                                        │
│  └── 推荐用于生产环境                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

mod_php 方式 #

安装 mod_php #

bash
# Ubuntu/Debian
sudo apt install libapache2-mod-php

# CentOS/RHEL
sudo yum install php

# 查看已安装版本
php -v

配置 mod_php #

apache
# ============================================
# mod_php 配置
# ============================================

# 加载模块(通常自动加载)
LoadModule php_module modules/libphp.so

# 设置 PHP 文件处理器
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

# 设置 PHP 源码文件处理器
<FilesMatch \.phps$>
    SetHandler application/x-httpd-php-source
</FilesMatch>

# 添加索引文件
DirectoryIndex index.php index.html

# PHP 配置目录
PHPIniDir /etc/php/8.1/apache2

PHP 配置文件 #

ini
; /etc/php/8.1/apache2/php.ini

; 基础配置
memory_limit = 256M
upload_max_filesize = 50M
post_max_size = 50M
max_execution_time = 60
max_input_time = 60

; 错误处理
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log

; 安全配置
expose_php = Off
allow_url_fopen = Off
allow_url_include = Off

; 会话配置
session.save_path = "/var/lib/php/sessions"
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1

; 时区
date.timezone = Asia/Shanghai

虚拟主机配置 #

apache
# ============================================
# mod_php 虚拟主机配置
# ============================================

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    
    <Directory /var/www/example>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        DirectoryIndex index.php index.html
    </Directory>
    
    # PHP 配置覆盖
    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>
    
    # 错误日志
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

PHP-FPM 方式 #

安装 PHP-FPM #

bash
# Ubuntu/Debian
sudo apt install php-fpm

# CentOS/RHEL
sudo yum install php-fpm

# 启动 PHP-FPM
sudo systemctl start php8.1-fpm
sudo systemctl enable php8.1-fpm

# 检查状态
sudo systemctl status php8.1-fpm

启用代理模块 #

bash
# Ubuntu/Debian
sudo a2enmod proxy
sudo a2enmod proxy_fcgi
sudo systemctl restart apache2

PHP-FPM 配置 #

ini
; /etc/php/8.1/fpm/pool.d/www.conf

[www]
; 进程管理
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; 进程池配置
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

; 慢请求日志
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s

; 状态页面
pm.status_path = /php-fpm-status
ping.path = /php-fpm-ping

; 环境变量
clear_env = no

Apache 配置 PHP-FPM #

apache
# ============================================
# PHP-FPM 配置(通过文件匹配)
# ============================================

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    
    <Directory /var/www/example>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # PHP-FPM 代理
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>
    
    # 索引文件
    DirectoryIndex index.php index.html
    
    # 日志
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

使用 ProxyPassMatch #

apache
# ============================================
# PHP-FPM 配置(通过 ProxyPassMatch)
# ============================================

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    
    # PHP-FPM 代理
    ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php8.1-fpm.sock|fcgi://localhost/var/www/example/
    
    # 目录权限
    <Directory /var/www/example>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # 索引文件
    DirectoryIndex index.php index.html
</VirtualHost>

全局 PHP-FPM 配置 #

apache
# ============================================
# 全局 PHP-FPM 配置
# /etc/apache2/conf-available/php8.1-fpm.conf
# ============================================

# 目录索引
DirectoryIndex index.php index.html

# PHP 文件处理器
<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
</FilesMatch>

# 代理配置
<Proxy "fcgi://localhost">
    ProxySet timeout=60
</Proxy>

# 禁止访问 PHP 文件(上传目录)
<Directory /var/www/html/uploads>
    <FilesMatch \.php$>
        Require all denied
    </FilesMatch>
</Directory>

PHP-FPM 进程池配置 #

进程管理器模式 #

text
┌─────────────────────────────────────────────────────────────┐
│                    PHP-FPM 进程管理模式                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  static(静态)                                             │
│  固定数量的子进程                                           │
│  pm.max_children = 50                                       │
│  适合高流量、内存充足的服务器                               │
│                                                             │
│  dynamic(动态)                                            │
│  动态调整进程数量                                           │
│  pm.max_children = 50                                       │
│  pm.start_servers = 5                                       │
│  pm.min_spare_servers = 5                                   │
│  pm.max_spare_servers = 10                                  │
│  适合流量波动的场景                                         │
│                                                             │
│  ondemand(按需)                                           │
│  按需创建进程                                               │
│  pm.max_children = 50                                       │
│  pm.process_idle_timeout = 10s                              │
│  适合低流量、资源受限的服务器                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

进程池配置示例 #

ini
; ============================================
; 高性能配置(8核 16GB 内存)
; ============================================

[www]
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000

; ============================================
; 低内存配置(2核 4GB 内存)
; ============================================

[www]
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500

; ============================================
; 高并发配置
; ============================================

[www]
pm = static
pm.max_children = 200
pm.max_requests = 1000

多进程池配置 #

ini
; /etc/php/8.1/fpm/pool.d/www.conf

; 默认池
[www]
listen = /run/php/php8.1-fpm.sock
pm = dynamic
pm.max_children = 50

; API 专用池
[api]
listen = /run/php/php8.1-fpm-api.sock
pm = dynamic
pm.max_children = 30
pm.start_servers = 5

; 后台任务池
[worker]
listen = /run/php/php8.1-fpm-worker.sock
pm = static
pm.max_children = 10
apache
# Apache 配置多池
<VirtualHost *:80>
    ServerName api.example.com
    DocumentRoot /var/www/api
    
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.1-fpm-api.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

PHP-FPM 状态监控 #

启用状态页面 #

apache
# ============================================
# PHP-FPM 状态页面
# ============================================

<Location /php-fpm-status>
    SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    Require ip 192.168.1.0/24
</Location>

<Location /php-fpm-ping>
    SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    Require all granted
</Location>

查看状态 #

bash
# 查看状态
curl http://localhost/php-fpm-status

# JSON 格式
curl http://localhost/php-fpm-status?json

# 详细信息
curl http://localhost/php-fpm-status?full

# 健康检查
curl http://localhost/php-fpm-ping

安全配置 #

上传目录安全 #

apache
# ============================================
# 上传目录安全配置
# ============================================

<Directory /var/www/html/uploads>
    # 禁止执行 PHP
    <FilesMatch \.php$>
        Require all denied
    </FilesMatch>
    
    # 或使用 php_flag(mod_php)
    php_flag engine off
    
    # 限制文件类型
    <FilesMatch "\.(jpg|jpeg|png|gif|pdf)$">
        Require all granted
    </FilesMatch>
    
    # 禁止 .htaccess
    AllowOverride None
</Directory>

PHP 安全配置 #

ini
; ============================================
; PHP 安全配置
; ============================================

; 隐藏 PHP 版本
expose_php = Off

; 禁用危险函数
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,eval

; 禁用危险类
disable_classes = 

; 限制文件包含
allow_url_fopen = Off
allow_url_include = Off

; 限制内存
memory_limit = 256M

; 限制执行时间
max_execution_time = 60

; 限制上传
upload_max_filesize = 10M
post_max_size = 10M

; 会话安全
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = Strict

性能优化 #

OPcache 配置 #

ini
; ============================================
; OPcache 配置
; ============================================

opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.max_wasted_percentage = 10
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
opcache.fast_shutdown = 1

; 生产环境推荐
opcache.validate_timestamps = 0
; 需要手动清除缓存或重启 PHP-FPM

JIT 配置(PHP 8+) #

ini
; ============================================
; JIT 配置
; ============================================

opcache.jit_buffer_size = 100M
opcache.jit = 1255

; JIT 模式
; 1255 = tracing + CPU-specific optimization
; 1235 = tracing + generic optimization
; 1254 = function + CPU-specific optimization

完整配置示例 #

apache
# ============================================
# 完整 PHP-FPM 配置示例
# ============================================

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example/public
    
    # PHP-FPM 代理
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>
    
    # 代理超时
    <Proxy "fcgi://localhost">
        ProxySet timeout=60
    </Proxy>
    
    # 目录配置
    <Directory /var/www/example/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        DirectoryIndex index.php index.html
    </Directory>
    
    # 保护敏感目录
    <Directory /var/www/example/storage>
        Require all denied
    </Directory>
    
    <Directory /var/www/example/vendor>
        Require all denied
    </Directory>
    
    # 上传目录安全
    <Directory /var/www/example/public/uploads>
        <FilesMatch \.php$>
            Require all denied
        </FilesMatch>
    </Directory>
    
    # 隐藏服务器信息
    ServerTokens Prod
    ServerSignature Off
    
    # 日志
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

下一步 #

掌握了 PHP 集成后,继续学习 Python 集成,了解如何配置 Apache 与 Python 应用的集成!

最后更新:2026-03-29