跨平台PHP开发需统一路径命名(全小写)、锁死PHP版本、弃用$_SERVER['DOCUMENT_ROOT']、启动时检测扩展,避免隐性依赖导致线上故障。

Windows 和 Linux 下 file_exists() 路径大小写敏感性不一致
PHP 在 Windows 上对文件路径不区分大小写,file_exists('Config.php') 和 file_exists('config.php') 都可能返回 true;Linux 下则严格区分,小写错一个字母就返回 false。这会导致本地开发(Win)正常、上线(Linux)报错。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 所有
include、require、file_exists()中的路径,统一用小写命名 + 小写引用,避免依赖系统行为 - 用
realpath()或__DIR__拼接路径,而不是拼字符串:include __DIR__ . '/config/database.php';,减少斜杠方向和相对路径歧义 - CI/CD 流程中加一条检查:用
ls -l(Linux)或dir(Windows)确认实际文件名大小写,别信 IDE 显示名
PHP 版本差异导致 json_encode() 输出不一致
PHP 7.3+ 默认启用 JSON_UNESCAPED_UNICODE,而旧版本默认转义中文为 \uXXXX;另外,JSON_INVALID_UTF8_IGNORE 在 7.2 才引入,7.1 及以下直接报错。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 跨平台项目必须锁死 PHP 版本(如
composer.json中写"php": "^7.4 || ^8.0"),不能只写">=7.0" - 输出 JSON 前显式指定选项:
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),不依赖默认行为 - 接收前端 JSON 时,用
json_last_error()检查错误类型,JSON_ERROR_UTF8在老版本无法跳过,得提前用mb_convert_encoding()清理
$_SERVER['DOCUMENT_ROOT'] 在 CLI 和 Web 环境下行为完全不同
CLI 模式下 $_SERVER['DOCUMENT_ROOT'] 通常为空或未定义,但很多旧代码直接拿来拼路径,结果在命令行跑迁移或队列时出错;Web 环境下它又依赖 Web 服务器配置(Apache vs Nginx 的 root 指令位置不同)。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 彻底弃用
$_SERVER['DOCUMENT_ROOT']拼路径,改用__DIR__或dirname(__FILE__)向上定位 - 如果必须兼容多入口(web/index.php、cli/artisan),把根目录抽象成常量:
define('BASE_PATH', dirname(__DIR__));,在各入口文件顶部统一定义 - Nginx 配置里不要靠
fastcgi_param DOCUMENT_ROOT注入,CLI 根本不走 FastCGI,这种参数毫无意义
扩展缺失不是报错而是静默失败,比如 ext-intl 或 ext-mbstring
某些函数(mb_strlen()、collator_create())在扩展未加载时不会抛出 Fatal error,而是返回 null 或 false,逻辑继续往下走,直到某个地方突然 strlen(null) 报错,堆栈根本看不出源头。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 启动时集中检测关键扩展:
extension_loaded('mbstring') || die('ext-mbstring required');,别等用到再判断 - Docker 或部署脚本里加
php -m | grep -E '^(intl|mbstring|curl|json)$',比phpinfo()更可靠 - IDE 中配置 PHP 解释器路径时,务必指向目标环境的
php(比如/usr/bin/php),否则本地提示“函数不存在”但实际运行又没问题,纯属误导
跨平台真正的麻烦不在语法,而在那些「看起来能跑」却在特定环境下悄悄失效的隐性依赖——路径、编码、扩展、超全局变量,全得一个个掰开验货。漏掉一个,线上就少个功能,还很难复现。











