dirname() 是纯字符串操作函数,不查文件系统、不解析 .. 或 .,仅按斜杠分割并移除末段;如 dirname('foo') 返回 '.',dirname(__FILE__) 返回绝对路径的上一级目录。

直接说结论:dirname() 是纯字符串操作函数,不查文件系统,也不处理 .. 或 .,只按斜杠切路径、删最后一段。用错地方会返回意料之外的结果,比如 dirname('foo') 得到 '.',而不是空或报错。
为什么 dirname(__FILE__) 常见但容易误解
它本质是把当前文件的完整路径(如 /var/www/app/index.php)砍掉 index.php,留下 /var/www/app。但注意:
-
__FILE__是绝对路径,dirname(__FILE__)也是绝对路径 —— 这点很关键,别当成相对路径用 - 想上两级?写
dirname(dirname(__FILE__)),不是dirname(__FILE__, 2)(PHP 7+ 才支持第二个参数) - Windows 下混用
和/没问题,dirname('C:www est.php')和dirname('C:/www/test.php')都返回C:www - 如果
__FILE__被意外拼接成相对路径(比如__DIR__ . '/../lib'),再传给dirname()就没意义了 —— 它不会帮你规范化
dirname($path, $levels) 的层级逻辑和陷阱
PHP 7.0+ 支持第二个参数 $levels,表示“向上跳几级”,但它的行为不是递归解析,而是简单重复执行 dirname() $levels 次:
-
dirname('/a/b/c', 1)→'/a/b' -
dirname('/a/b/c', 2)→'/a' -
dirname('/a', 2)→ 先得'/',再对'/'执行一次dirname(),结果仍是'/'(不是报错) -
dirname('foo/bar', 3)→'.'(因为foo/bar→foo→'.'→'.') - 传入 0 或负数会警告:
Warning: dirname(): Invalid levels value
和 pathinfo()、basename() 混用时的常见错误
这三个函数都只做字符串拆分,互不替代,但常被误当“路径解析器”用:
立即学习“PHP免费学习笔记(深入)”;
-
basename('/path/to/file.txt')返回'file.txt';dirname('/path/to/file.txt')返回'/path/to'—— 二者拼起来 ≠ 原路径(缺了结尾斜杠) -
pathinfo($p, PATHINFO_DIRNAME)和dirname($p)在绝大多数情况下等价,但pathinfo()多一个PATHINFO_FILENAME选项,dirname()更轻量 - 不要用
dirname()处理带查询参数的 URL 字符串,比如dirname('https://example.com/a/b?c=d')返回'https://example.com/a'—— 它根本不管协议或问号,只认斜杠 - 遇到 Windows UNC 路径(如
\servershareile.txt),dirname()行为未定义;应先用str_replace()或正则预处理
最易被忽略的一点:它完全不关心路径是否存在,也不处理编码问题。中文路径在 Windows 上出错,往往不是 dirname() 的锅,而是当前代码页和实际文件名编码不匹配 —— 函数本身只按字节切,不转码。



















