dirname

(PHP 4, PHP 5, PHP 7, PHP 8)

dirname返回父目录的路径

描述

dirname(string $path, int $levels = 1): string

给定包含文件或目录路径的字符串,此函数将返回当前目录的 levels 级父目录的路径。

注意:

dirname() 对输入字符串进行简单操作,不了解实际文件系统或路径组件(例如“..”)。

警告

在 Windows 上,dirname() 假设当前设置的代码页,因此,为了让它看到包含多字节字符路径的正确目录名称,必须设置匹配的代码页。如果 path 包含当前代码页中无效的字符,dirname() 的行为将是未定义的。

在其他系统上,dirname() 假设 path 以 ASCII 兼容的编码进行编码。否则,函数的行为将是未定义的。

参数

path

一个路径。

在 Windows 上,斜杠 (/) 和反斜杠 (\) 都用作目录分隔符字符。在其他环境中,它是正斜杠 (/)。

levels

要向上移动的父目录数量。

这必须是一个大于 0 的整数。

返回值

返回父目录的路径。如果 path 中没有斜杠,则返回一个点('.'),表示当前目录。否则,返回的字符串是 path,其中任何尾随的 /component 都已删除。

警告

在循环中使用此函数时要小心,因为该循环可能会到达顶层目录,从而导致无限循环。

<?php
dirname
('.'); // 将返回 '.'.
dirname('/'); // 将在 Windows 上返回 `\`,在 *nix 系统上返回 '/'。
dirname('\\'); // 将在 Windows 上返回 `\`,在 *nix 系统上返回 '.'。
dirname('C:\\'); // 将在 Windows 上返回 'C:\',在 *nix 系统上返回 '.'。
?>

变更日志

版本 描述
7.0.0 添加了可选的 levels 参数。

示例

示例 #1 dirname() 示例

<?php
echo dirname("/etc/passwd") . PHP_EOL;
echo
dirname("/etc/") . PHP_EOL;
echo
dirname(".") . PHP_EOL;
echo
dirname("C:\\") . PHP_EOL;
echo
dirname("/usr/local/lib", 2);

上面的示例将输出类似于以下内容

/etc
/ (or \ on Windows)
.
C:\
/usr

参见

添加注释

用户贡献的注释 29 个注释

49
y dot a dot dejong at singular dot of dot alumni dot utwente dot nl
9 年前
从 PHP 5.3.0 开始,您可以使用 __DIR__ 作为 dirname(__FILE__) 的替代品
35
tobylewis at mac dot com
19 年前
由于给出的示例中的路径只有两个部分(例如“/etc/passwd”),因此不清楚 dirname 是返回父目录的单个路径元素还是返回直到父目录(包括父目录)的整个路径。从实验结果来看,似乎是后者。

例如

dirname('/usr/local/magic/bin');

返回 '/usr/local/magic' 而不是仅 'magic'

此外,不清楚 dirname 实际上返回路径的最后一个项目的父目录,无论最后一个项目是目录还是文件。(即,人们可能会认为,如果给定的路径是目录,那么 dirname 将返回整个原始路径,因为那是一个目录名称。)

此外,路径末尾存在目录分隔符并不一定表示路径的最后一个项目是目录,因此

dirname('/usr/local/magic/bin/'); #注意最后的 '/'

将返回与我上面示例相同的结果。

简而言之,这似乎更像是一个字符串操作函数,它从路径字符串中剥离最后一个非空文件或目录元素。
43
tapken at engter dot de
22 年前
获取当前包含文件的目录

<?php
dirname
(__FILE__);
?>

例如,如果一个名为 'database.init.php' 的脚本从文件系统的任何位置包含,并且它希望包含脚本 'database.class.php'(位于同一目录中),您可以使用

<?php
include_once(dirname(__FILE__) . '/database.class.php');
?>
4
bobray at softville dot com
5 年前
请注意,如果您在 Windows 上调用 dirname(__FILE__),您可能会获得反斜杠。如果您随后尝试使用 str_replace() 或 preg_replace() 使用正斜杠在搜索模式中替换路径的一部分,则不会匹配。您可以在进行任何转换之前使用 $path = str_replace('\\', '/' ,$path) 来规范化路径
10
joe dot naylor at gmail dot com
15 年前
dirname 函数通常不会在末尾返回斜杠,这可能会鼓励您使用类似于以下代码创建链接
$url = dirname($_SERVER['PHP_SELF']) . '/somepage.php';

但是,如果指定的路径是根目录,则 dirname 会返回斜杠,因此在这种情况下 $url 将变为 '//somepage.php'。例如,如果您将该 URL 作为表单的 action 放置,则提交表单将尝试转到 http://somepage.php.

当我在具有路径的 URL 上编写站点时遇到了这个问题,www.somehost.com/client/somepage.php,上面的代码工作得很好,但随后我想将其放在子域上,client.somehost.com/somepage.php,在那里事情开始出现故障。

最好的解决方案是创建一个生成绝对 URL 的函数,并在整个站点中使用它,但创建一个安全的 dirname 函数(以及一个 htaccess 重写以防万一修复双斜杠)为我解决了这个问题

<?php
function safe_dirname($path)
{
$dirname = dirname($path);
return
$dirname == '/' ? '' : $dirname;
}
?>
3
Tom
16 年前
扩展 Anonymous 的评论,这并不一定正确。如果用户使用安全协议,则此 URL 不准确。这将正常工作

<?php

// 用户是否使用 HTTPS?
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')) ? 'https://' : 'http://';

// 完善 URL
$url .= $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);

// 输出 URL
echo $url;

?>
3
klugg this-is-junk at tlen dot pl
19 年前
注意这一点。Dirname 可能会搞乱斜杠。
在 Windows 上,Apache

<?php
echo '$_SERVER[PHP_SELF]: ' . $_SERVER['PHP_SELF'] . '<br />';
echo
'Dirname($_SERVER[PHP_SELF]: ' . dirname($_SERVER['PHP_SELF']) . '<br>';
?>

输出

$_SERVER[PHP_SELF]: /index.php
Dirname($_SERVER[PHP_SELF]: \
1
nhl261 at yahoo dot com
13 年前
像往常一样,要包含或引入文件,我们使用这个
<?php
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'my_file.php';
?>

在极少数情况下,当前文件位于根目录,dirname 会返回 C:\ 或 /,然后上面的行包含 2 个斜杠 \\ 或 //
为了处理这种情况,我们使用 rtrim 来清除斜杠。
<?php
require rtrim(dirname(__FILE__), '/\\') . DIRECTORY_SEPARATOR . 'my_file.php';
?>

此外,dirname 的另一个用途是获取虚拟目录(URL 路径),问题与上面一样,我们在连接字符串之前必须检查和处理
1
ts at dev dot websafe dot pl
16 年前
在 script.php 中,我需要知道包含目录的名称。例如,如果我的脚本位于 '/var/www/htdocs/website/somedir/script.php',我需要以统一的方式知道 'somedir'。

解决方法是
<?php
$containing_dir
= basename(dirname(__FILE__));
?>
0
iam at shaz3e dot com
10 年前
文件位于本地:F:\localhost\www\Shaz3e-ResponsiveFramework\S3-CMS\_source

本地主机路径:http://s3lab.com/Shaz3e-ResponsiveFramework/S3-CMS/_source/

示例 1:dirname($_SERVER['PHP_SELF']); // 输出:/Shaz3e-ResponsiveFramework/S3-CMS/_source

示例 2:"http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']); // 输出:http://s3lab.com/Shaz3e-ResponsiveFramework/S3-CMS/_source

示例 3:$_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']); // 输出:s3lab.com/Shaz3e-ResponsiveFramework/S3-CMS/_source
0
hans111 at yahoo dot com
17 年前
相同的功能,但改进了一点,将使用 REQUEST_URI,如果不可用,将使用 PHP_SELF,如果不可用,将使用 __FILE__,在这种情况下,函数必须位于同一个文件中。它应该可以工作,在 Windows 和 *NIX 上。

<?php
function my_dir(){
return
end(explode('/', dirname(!empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : !empty($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : str_replace('\\','/',__FILE__))));
}

?>
0
soywiz at hotmail dot com
20 年前
你可以用它来获取父目录

dirname(dirname(__FILE__))

... 包含一个相对于文件路径的文件

include(dirname(__FILE__) . '/path/relative/file_to_include.php');

.. 等等。
-1
frederikreiss at gmx dot de
10 年前
递归 dirname 怎么样?要获取目录中 $count 级别的向上目录。

<?php

function r_dirname($path, $count=1){
if (
$count > 1){
return
dirname(r_dirname($path, --$count));
}else{
return
dirname($path);
}
}
-1
subzey at immelman dot ru
13 年前
在某些情况下(我无法找到依赖项),如果解析的字符串为 UTF-8,basename 和 dirname 可能会返回不正确的值。

例如,dirname("glossary/задний-фокус") 将返回 "glossary",basename("glossary/задний-фокус") 将返回 "-фокус"。

快速修复是
str_replace("!$!", "", dirname(str_replace("/", "!$!/!$!", $q)))
-1
Anonymous
16 年前
一个简单的方法来显示包含文件的文件夹的 www 路径...

echo "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
-1
legolas558 dot sourceforge comma net
18 年前
获取当前解析的 PHP 脚本的文件夹的绝对路径的最佳方法是

<?php

if (DIRECTORY_SEPARATOR=='/')
$absolute_path = dirname(__FILE__).'/';
else
$absolute_path = str_replace('\\', '/', dirname(__FILE__)).'/';

?>

这将导致一个绝对的 unix 样式路径,它在 Windows 下的 PHP5 中也可以正常工作,在那里混合 '\' 和 '/' 可能会造成问题。

[编辑:danbrown AT php DOT net:应用了作者从后续说明中提供的修复。]
-4
rudecoder at yahoo dot com
21 年前
dirname 可以用以下单行代码来创建自引用的 Web 脚本。

<?php
$base_url
= str_replace($DOCUMENT_ROOT, "", dirname($PHP_SELF));
?>

在像这样的文件中使用这种方法

/home/mysite/public_html/wherever/whatever.php

将返回

/wherever

现在 $base_url 可用于 HTML 中引用同一目录中的其他脚本。

示例

href='<?=$base_url?>/myscript.php'
-4
Xedecimal at gmail dot com
17 年前
获取当前脚本的绝对路径

<?php
dirname
(__FILE__)
?>

获取当前脚本的 Web 服务器相对路径...

<?php
function GetRelativePath($path)
{
$npath = str_replace('\\', '/', $path);
return
str_replace(GetVar('DOCUMENT_ROOT'), '', $npath);
}
?>

稍后

<?php
GetRelativePath
(dirname(__FILE__));
?>

如果有更好的方法,请提出建设性的批评!
-3
webyazilimci84 at gmail dot com
14 年前
在我的基于 MVC 的框架中,我像下面这样进行 BASE_PATH 和 BASE_URL 定义,两者在框架中都能很好地工作,没有问题。

index.php

define('BASE_PATH',realpath('.'));
define('BASE_URL', dirname($_SERVER["SCRIPT_NAME"]));

BASE_PATH 用于服务器端包含。
BASE_URL 用于客户端包含(脚本、css 文件、图像等)。
-4
Zingus J. Rinkle
16 年前
我在这里看到的多数 mkpath() 函数看起来又长又复杂。
这是我的

<?php
function mkpath($path)
{
if(@
mkdir($path) or file_exists($path)) return true;
return (
mkpath(dirname($path)) and mkdir($path));
}
?>

未在 Windows 上测试,但 dirname() 手册说它应该可以工作。
-6
ken dot forslund at hp dot com
15 年前
层次化包含树的关键问题在于 PHP 处理相对于原始文件而不是当前包含文件的包含路径。

解决方法是为所有包含路径添加前缀
<?php str_replace('//','/',dirname(__FILE__)); ?>

这将生成一个相对于当前文件的基路径,然后允许类似于 C/C++ 的包含行为。

因此,要包含父目录中的文件 1
<?php require_once( str_replace('//','/',dirname(__FILE__).'/') .'../parent.php'); ?>

要包含同一目录中的文件
<?php require_once( str_replace('//','/',dirname(__FILE__).'/') .'neighbor.php'); ?>

要包含子目录中的文件
<?php require_once( str_replace('//','/',dirname(__FILE__).'/') .'folder/sub.php'); ?>

请注意,我们引用的所有路径都不得以 / 开头,并且必须相对于当前文件,以便正确连接。
-6
minimalist at intelligence dot com
12 年前
如果您想获取脚本的父父目录,可以使用以下代码

<?php
//示例脚本路径:home/content/en/script.php
$parentparentdir=basename(dirname(dirname(__FILE__)));
echo
$parentparentdir; //将输出 'content'
?>
-6
Holger Th?lking
19 年前
如果您只是想确定某个文件是否位于某个目录内或其下,例如,用于白名单验证,则以下函数可能对您有用

<?php
function in_dir ($file, $in_dir)
{
$dir = realpath ($file);
$in_dir = realpath ($in_dir);

if (!
is_dir ($file)) {
$dir = dirname ($file);
}

do {
if (
$dir === $in_dir) {
$is_in_dir = TRUE;
break;
}
} while (
$dir !== ($dir = dirname ($dir)));

return (bool) @
$is_in_dir;
}
?>
-7
rmahase at gmail dot com
16 年前
这个小函数获取顶层公共目录

例如,http://www.mysite.com/directory1/file.php

http://www.mysite.com/directory1/directory2/directory3/file.php

都将返回 "directory1" ... 这是顶层目录

<?php
function public_base_directory()
{
//获取公共目录结构,例如 "/top/second/third"
$public_directory = dirname($_SERVER['PHP_SELF']);
//将每个目录放入数组中
$directory_array = explode('/', $public_directory);
//获取目录字符串数组中最高的或顶层的
$public_base = max($directory_array);

return
$public_base;
}
?>
-8
Yousef Ismaeil Cliprz
11 年前
如果您想从项目路径调用文件,可以获得最佳根路径。

确保在 www/index.php 中定义了此项

或位于 www/ 根目录内的核心文件。

<?php

/**
* @def (string) DS - 目录分隔符。
*/
define("DS","/",true);

/**
* @def (resource) BASE_PATH - 获取基路径。
*/
define('BASE_PATH',realpath(dirname(__FILE__)).DS,true);

?>

您可以随时调用任何文件,而不会遇到任何问题

<?php

include BASE_PATH.'inc/class.php';

?>
-7
andrey at php dot net
21 年前
用于写入权限检查的代码

<?php
error_reporting
(E_ALL);
$dir_name = '/var/www/virtual/phpintra/htdocs/php/';
do {
$b_is_writable = is_writable($dir_name);
echo
sprintf("Dir[%s]Writable[%s]\n", $dir_name, $b_is_writable? 'YES':'NO');
}while ((
$dir_name = dirname($dir_name)) !='/');
?>
-6
dave at corecomm dot us
21 年前
我非常感谢 Fredrich Echol 的建议 (rwf at gpcom dot net),关于如何找到基路径,但发现当初始脚本已经在根文件夹中时它会失败 -- dirname('/rootscript.php')=='/' 和 dirname('/include/includescript.php')=='/include' 具有相同的斜杠数量。这是我现在使用的变体

<?php
if (!defined("BASE_PATH")) define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME'])=='/' ? './' : str_repeat("../", substr_count(dirname($_SERVER["SCRIPT_NAME"]), "/")));
?>

这显式地检查根路径 (/),如果我们在根文件夹中,则使用 './' 作为基路径。
我把这个放在任何调用另一个文件的顶部/附近。(我出于自己的方便使用了 define;它应该与变量一起工作,并且无需测试是否已经执行了它。)

请注意,在这两种情况下(根文件夹脚本和非根文件夹脚本),BASE_PATH 将包含尾部斜杠。至少在 Darwin(Mac OS X)上的 Apache 中,您可以 include(BASE_PATH.'/myfile.php'); 并且双斜杠不会导致任何问题,与 include(BASE_PATH.'myfile.php'); 产生相同的结果。
-7
qeremy (!) gmail
8 年前
在 PHP 7 之后;
<?php
print dirname("/usr/local/lib", 2); # /usr
?>

在 PHP 7 之前;
<?php
print dirname(dirname("/usr/local/lib")); # /usr

# or
function dirname_with_levels($path, $levels = 1) {
while (
$levels--) {
$path = dirname($path);
}
return
$path;
}
print
dirname_with_levels("/usr/local/lib", 2); # /usr
?>
-16
renich at woralelandia dot com
19 年前
--- 由 [email protected] 编辑 ---
您也可以查看 getcwd() 函数
--- 编辑结束 ---

一个不错的“当前目录”函数。

function current_dir()
{
$path = dirname($_SERVER[PHP_SELF]);
$position = strrpos($path,'/') + 1;
print substr($path,$position);
}

current_dir();

我发现这对很多东西都很有用!您可以使用目录名称作为模块名称来维护一个模块化的网站。至少我希望 PHP 开发人员能够将此添加到函数列表中!

如果有任何类似的东西,请告诉我。
To Top