mkdir失败时需用error_get_last()捕获最近未处理的PHP错误,因其对权限不足、父目录不存在等系统级失败有效;但须紧接false判断后调用,且无法捕获异常或已被处理的错误。

mkdir 失败时,@ 抑制错误并不能让你“看不见错误”,只是不让警告显示出来;真正的原因仍存在,需要用 error_get_last() 主动捕获。但要注意:这个函数只返回**最近一次未被捕获的 PHP 错误**,且对 mkdir 这类系统级失败(如权限不足、父目录不存在、路径过长)特别有效。
先确认 mkdir 是否真的失败了
不要只看返回值是否为 false —— 它可能因多种原因失败,而你得区分是逻辑问题还是系统限制:
- 检查返回值:
if (mkdir($path, 0755, true) === false) - 立即调用
error_get_last(),不能隔任何语句(包括 echo、赋值、函数调用) - 若返回 null,说明没触发 PHP 层错误(比如路径语法合法但磁盘已满,此时可能静默失败,需配合
is_dir()验证结果)
获取并解读 error_get_last() 的错误信息
mkdir 失败时常见的错误 message 通常包含关键词,例如:
-
"Permission denied"→ 当前 Web 用户(如 www-data)对父目录无写权限 -
"No such file or directory"→ 上级目录不存在,且你没设$recursive = true -
"File exists"→ 目录已存在(注意:mkdir 在目录存在时也返回 false,不是报错,所以error_get_last()可能为 null) -
"Disk quota exceeded"或"Too many levels of symbolic links"→ 系统级限制,需运维介入
建议这样写:
$result = @mkdir($path, 0755, true);<br>if ($result === false) {<br> $err = error_get_last();<br> if ($err) {<br> error_log("mkdir failed: {$path} – {$err['message']} ({$err['file']}:{$err['line']})");<br> } else {<br> error_log("mkdir failed silently: {$path} – check parent dir existence & permissions");<br> }比 error_get_last() 更靠前的预防措施
依赖错误捕获是补救,提前预检才能减少失败:
- 用
dirname($path) 获取父目录,再用is_writable()检查它是否可写 - 用
realpath(dirname($path))或__DIR__拼接路径,避免相对路径在 CLI/Web 下行为不一致 - 递归创建前,先确保上级目录存在:可先
mkdir(dirname($path), 0755, true)再建子目录 - 权限不要硬写 0777 —— 生产环境用 0755,并确认 Web 服务器用户拥有该目录所有权(如 chown www-data:www-data /var/www/cache)
注意 error_get_last() 的局限性
它不适用于以下情况:
- mkdir 成功但后续 chmod 失败(那是另一个错误,需单独捕获)
- 错误被自定义错误处理器(
set_error_handler)捕获且未返回 false - 发生的是异常(Exception),而非 PHP 错误(
error_get_last()对异常无效) - 脚本中途 exit/die 或被 kill,可能来不及记录
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











