php网站开启https的关键是web服务器(apache/nginx)正确加载ssl证书、监听443端口并透传https状态;若未显式配置mod_ssl、证书路径错误、私钥不匹配或未设置fastcgi_param https on/sslengine on,则$_server['https']为空,导致重定向错乱、混合内容及url生成异常。

PHP网站本身不处理HTTPS,开启HTTPS的关键是Web服务器(Apache/Nginx)正确加载SSL证书、监听443端口,并把加密状态准确透传给PHP。跳过服务器配置或证书格式不对,$_SERVER['HTTPS']就永远为空,重定向会错、资源会混载、API调用可能被拒绝。
Apache启用mod_ssl并确认证书路径可读
很多本地环境(如phpEnv、XAMPP、WAMP)默认禁用SSL模块,光放证书文件没用。必须显式启用mod_ssl并验证Apache能读取证书文件。
- 打开
httpd.conf,取消注释这两行:LoadModule ssl_module modules/mod_ssl.so和Include conf/extra/httpd-ssl.conf - 检查
httpd-ssl.conf中SSLCertificateFile和SSLCertificateKeyFile的路径是否为绝对路径或相对于ServerRoot的正确相对路径(例如"conf/ssl/localhost+3.pem") - 在终端执行
httpd -t,输出Syntax OK才代表路径无误;若报SSLCertificateFile: file '/xxx/localhost.crt' does not exist or is empty,说明路径错或文件权限不足(Windows下注意反斜杠转义) - 证书文件需放在Apache有读取权限的目录里,不能放在用户桌面或带空格/中文路径下
Nginx配置ssl_certificate时必须合并中间证书
Nginx不支持单独指定中间证书,ssl_certificate必须是“域名证书 + 中间证书”拼接后的PEM文件,否则Chrome/Firefox会显示NET::ERR_CERT_AUTHORITY_INVALID。
- 不要只放
yourdomain.crt——它通常只是叶证书;要把它和CA提供的ca-bundle.crt或fullchain.pem内容合并:用文本编辑器打开两个文件,把中间证书内容追加到域名证书后面(顺序不能反) - 私钥
ssl_certificate_key必须是未加密的RSA密钥(开头为-----BEGIN RSA PRIVATE KEY-----),如果生成时用了-aes256,需先用openssl rsa -in encrypted.key -out decrypted.key解密 - 检查Nginx配置语法:
nginx -t;若提示SSL_CTX_use_PrivateKey_file("/path/key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch),说明证书和私钥不匹配
PHP识别HTTPS依赖服务器显式设置环境变量
Apache/Nginx不会自动设$_SERVER['HTTPS'],必须手动声明。否则header("Location: https://...")可能死循环,Laravel/WordPress等框架的URL生成也会出错。
- Apache中,在
<virtualhost></virtualhost>内添加:SetEnv HTTPS on(不是SetEnvIf或RewriteRule模拟) - Nginx中,在
server块的location ~ \.php$里添加:fastcgi_param HTTPS on;(仅fastcgi_param有效,set $https on;无效) - 如果用了CDN或反向代理(如Nginx前置代理Apache),PHP可能收不到原始HTTPS信号,此时需检查
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https',但前提是代理已设置proxy_set_header X-Forwarded-Proto $scheme; - 别在PHP里硬编码
https://拼URL——用$_SERVER['HTTPS'] ?? 'off'动态判断协议,或统一走$_SERVER['REQUEST_SCHEME'](PHP 5.6.0+)
本地开发用mkcert生成含SAN的证书,别用openssl req
现代浏览器(Chrome 58+、Edge、Safari)强制要求证书包含subjectAltName(SAN),否则直接拦截且无法“高级→继续访问”。openssl req -x509生成的自签名证书默认不含SAN,必须手动加扩展,极易出错。
- 下载
mkcert(v1.4.8+),运行mkcert -install注入根证书到系统信任库(需管理员权限) - 生成证书时至少包含
localhost、127.0.0.1和::1:mkcert localhost 127.0.0.1 ::1,避免IPv6环境下访问失败 - 生成的
localhost+3.pem已自带完整SAN,无需再编辑openssl.cnf或写配置文件 - 证书文件名含
+3表示3个SAN条目,别手动改名——Apache/Nginx只认路径,不校验文件名
最容易被忽略的是:证书链完整性、私钥与证书配对验证、以及服务器是否真正把HTTPS环境变量传给了PHP进程。这三处任一出错,都会导致看似配置完成,但$_SERVER['HTTPS']为空或混合内容警告持续出现。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











