




mkdir()或file_put_contents()返回false的常见原因包括:目标目录不存在或不可写、mkdir未启用递归参数、Web与CLI用户权限差异、SELinux/AppArmor拦截、open_basedir限制及Windows路径转义问题。

PHP 创建文件或目录失败时直接返回 false,不是语法错误,而是运行时权限或路径问题。最常踩的坑是:你以为路径存在/可写,其实它根本不存在、父目录不可写、或 PHP 进程没权限。
file_put_contents() 要求**目标目录存在且可写**,不自动创建父级路径mkdir() 默认不递归创建多级目录,mkdir('/a/b/c', 0755, true) 才行(第三个参数必须为 true)www-data、nginx、apache)和 CLI 用户(如 root 或当前 shell 用户)权限不同,CLI 下能创建 ≠ Web 下能创建getsebool httpd_can_network_connect 类命令可查(Linux 发行版差异大)别靠肉眼判断路径,用代码验证:
var_dump(is_dir('/path/to/dir')); // 是否为目录
var_dump(is_writable('/path/to/dir')); // 是否可写(注意:某些系统对 sticky 目录返回 false)
var_dump(file_exists('/path/to/dir')); // 是否存在(目录或文件都算)
var_dump(error_get_last()); // 紧跟在失败操作后调用,看底层报错
特别注意:is_writable() 在 Windows 上可能误判,更稳妥的是尝试写一个临时文件再删掉:
$test = '/path/to/dir/.write_test';
if (file_put_contents($test, 'x') !== false && unlink($test)) {
echo "可写";
} else {
echo "不可写";
}
当 PHP 配置了 open_basedir(常见于共享主机或安全加固环境),所有文件操作只能在指定目录树内进行。超出范围的操作会静默失败,file_put_contents() 返回 false,但不会抛出异常或警告。
echo ini_get('open_basedir');,返回空字符串表示未启用/var/www/html/:/tmp/,则 /var/www/html/uploads/ 可写,但 /home/user/data/ 不行file_put_contents(): open_basedir restriction in effect,但默认不记录到 error_log,需确认 log_errors = On 且 error_reporting 包含警告Windows 不依赖 Unix 权限位,但仍有几处易错:
\ 在双引号字符串中是转义符,"C:\temp\file.txt" 实际变成 C: empile.txt —— 必须用正斜杠 / 或双反斜杠 \\
C:\Program Files、C:\Windows)默认禁止普通用户写入,即使你是管理员账户,UAC 也会拦截ApplicationPoolIdentity 或 LocalSystem 身份运行,需手动给目标目录添加该用户的“修改”权限(不是“完全控制”)路径拼接建议统一用 dirname(__FILE__) 或 __DIR__ + DIRECTORY_SEPARATOR,避免硬编码斜杠;权限问题永远优先查进程实际身份,而不是当前登录用户。