对于在 2.6.31 和更新的内核上遇到 is_dir() 在 CIFS 挂载点或这些挂载点内的目录返回 false 的任何人,请注意:显然,在新内核中,他们已开始默认使用 CIFS serverino 选项。对于 Windows 共享,这会导致巨大的 inode 编号,这显然会导致 is_dir() 返回 false。向 CIFS 挂载添加 noserverino 选项将防止这种情况。这可能只发生在 32 位系统上,但我没有 64 位安装来进行测试。
(PHP 4, PHP 5, PHP 7, PHP 8)
is_dir — 判断文件名是否为目录
filename
文件路径。如果 filename
是相对文件名,则相对于当前工作目录进行检查。如果 filename
是符号链接或硬链接,则会解析链接并进行检查。如果您启用了 open_basedir,则可能会有进一步的限制。
失败时,会发出 E_WARNING
。
示例 #1 is_dir() 示例
<?php
var_dump(is_dir('a_file.txt'));
var_dump(is_dir('bogus_dir/abc'));
var_dump(is_dir('..')); //向上一个目录
?>
以上示例将输出
bool(false) bool(false) bool(true)
注意: 此函数的结果会被缓存。详情请参见 clearstatcache()。
对于在 2.6.31 和更新的内核上遇到 is_dir() 在 CIFS 挂载点或这些挂载点内的目录返回 false 的任何人,请注意:显然,在新内核中,他们已开始默认使用 CIFS serverino 选项。对于 Windows 共享,这会导致巨大的 inode 编号,这显然会导致 is_dir() 返回 false。向 CIFS 挂载添加 noserverino 选项将防止这种情况。这可能只发生在 32 位系统上,但我没有 64 位安装来进行测试。
这是我用来解决问题的“is_dir”函数
function Another_is_dir ($file)
{
if ((fileperms("$file") & 0x4000) == 0x4000)
return TRUE;
else
return FALSE;
}
或者,更简单
function Another_is_dir ($file)
{
return ((fileperms("$file") & 0x4000) == 0x4000);
}
我不记得它来自哪里,但它运行良好。
我对必须包含完整路径才能使“is_dir”正常工作的问题的解决方案,作为一个完整的示例
<? // findfiles.php - “videoarchive”目录中的内容
$dir = 'images/videoarchive/'; // 从顶部开始的路径
$files = scandir($dir);
$files_n = count($files);
$i=0;
while($i<=$files_n){
// “is_dir” 只能从顶级目录工作,所以在文件之前附加 $dir
if (is_dir($dir.'/'.$files[$i])){
$MyFileType[$i] = "D" ; // D 代表目录
} else{
$MyFileType[$i] = "F" ; // F 代表文件
}
// 打印 itemNo、itemType(D/F) 和 itemname
echo '<br>'.$i.'. '. $MyFileType[$i].'. ' .$files[$i] ;
$i++;
}
?>
子目录处理中的陷阱
在努力处理子目录(跳过了某些子目录)并阅读帖子后,我意识到几乎没有人清楚地说明了问题所在。
常见的遍历目录代码是
-----------------------------------------
opendir("myphotos"); // 要从中处理的顶级目录(示例)
while (false !== ($fname = readdir($h_dir))) { // 处理当前目录(读取目录条目)
if ($fname{0} == '.') continue; // 通过第一个字符测试跳过 . 和 .. 目录
if (is_dir($fname)) call_own_subdir_process; // 通过调用例程处理此子目录
}
问题是
"is_dir()" 必须具有完整路径,否则它将跳过某些目录。因此,上述代码需要在文件名之前插入路径。这将对上述内容进行以下更改...
if (is_dir("myphotos\" . $fname)) call_own_subdir_process; // 跳过子目录
陷阱在于,如果没有完整路径,会发现一些子目录……希望这能澄清所有问题
在 win32 平台(Win XP SP3、Apache/2.2.11、PHP/5.2.9)上尝试(无“pear”)枚举已安装的驱动器时,我使用了
<?php
function echo_win_drives() {
for($c='A'; $c<='Z'; $c++)
if(is_dir($c . ':'))
echo $c . ': ';
}
?>
这产生了
A: C: D: E: F: G: H: I
啊哈!也许这是一个错误,或者更准确地说是一个限制,是 php 的一个限制。参见 http://bugs.php.net/bug.php?id=27792
该页面(上面)上发布了一个解决方法,它似乎对我有用
function is_dir_LFS($path){
return (('d'==substr(exec("ls -dl '$path'"),0,1))?(true):(false));
}
附注:我使用的是 PHP 4.3.10-16,帖子报告了直到 5.0 的这个问题
在 Apache Windows 上运行 PHP 5.2.0 时,我遇到了一个问题(可能与其他人描述的问题相同),其中 is_dir 即使目录可访问,也会为具有某些权限的目录返回 False。
奇怪的是,我能够通过更完整的路径来解决这个问题。例如,这仅在具有特定权限的子目录中显示“Works”(在这个目录中大约三分之一)。
$d = opendir("./albums/mydir");
while(false !== ($f = readdir($d))) {
echo "<hr />";
if(is_dir($f)) {
echo "<b>Works:" . $f . "</b>";
}
}
然而,这段代码对所有目录都能正常工作
$d = opendir("./albums/mydir");
while(false !== ($f = readdir($d))) {
echo "<hr />";
$dName = "./albums/mydir/" . $f;
if(is_dir($dName)) {
echo "<b>Works:" . $dName . "</b>";
}
}
我不理解第一段代码的命中率,但是第二段代码或许可以帮助遇到此问题的其他人。
关于检查空目录的一个说明
>>echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
这在Linux上无法正常工作。
即使目录中不存在文件,“.” 和 “..” 也会始终返回。
请注意,is_dir() 也适用于 ftp://.
例如
<?php
if(is_dir('ftp://user:pass@host/www/path/to/your/folder')) {
// 你的代码。
}
?>
但是请注意,如果由于凭据无效而连接失败,这将认为文件夹不存在并返回 FALSE。
请注意,此函数遵循符号链接。如果文件实际上是指向目录的符号链接,它将返回 true。
示例
<php
symlink(".", "testlink");
var_dump(is_dir("testlink"));
unlink("testlink");
?>
输出
bool(true)
(Windows 注:在最新版本的 Windows 中,只要你是管理员,就可以设置符号链接,但是你不能使用“unlink()”删除目录符号链接,你必须使用 shell 中的“rmdir testlink”才能将其删除。)
这是另一种测试目录是否为空的方法,我认为它比下面发布的方法简单得多
<?php
$dir = 'directory';
echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
此函数绕过了 open_basedir 限制。
<?
function my_is_dir($dir)
{
// 绕过 is_dir 和 fileperms 的 open_basedir 限制
$tmp_cmd = `ls -dl $dir`;
$dir_flag = $tmp_cmd[0];
if($dir_flag!="d")
{
// 不是 d;使用下一个字符(第一个字符可能是 's',仍然是目录)
$dir_flag = $tmp_cmd[1];
}
return ($dir_flag=="d");
}
?>
示例
<?
....
echo is_dir("/somewhere/i/dont/have/access/to");
?>
输出
Warning: open_basedir restriction in effect
<?
....
echo my_is_dir("/somewhere/i/dont/have/access/to");
?>
输出
true(或 false,取决于它是否……)
---
访问 puremango.co.uk 获取其他此类精彩内容
请注意,网上有很多文章暗示诸如 is_dir、opendir、readdir 之类的命令无法读取带有空格的路径。
在 Linux 系统上,这不是问题。
示例测试代码:
$dir = "Images/Soma ALbum Name with spaces";
echo $dir."<br/>";
// 打开目录并读取其内容
if (is_dir($dir)){
echo $dir."<br/>"; // 如果上面失败,则不会显示
if ($dh = opendir($dir)){
echo $dir."<br/>"; // 如果上面失败,则不会显示
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
echo $dir."<br/>"; // 如果上面失败,则不会显示
}
closedir($dh);
}
}
如果您使用的是 Mac 或其他存储有关目录布局等信息的系统,则该函数
function empty_dir($dir) {
if (($files = @scandir($dir)) && count($files) <= 3)
return true;
else
return false;
}
必须将 count($files) 与隐藏文件的数量进行比较!
例如,我使用的是 Mac,空目录显示给我三个文件:“.”、“..” 和“.DS_Store”,因此如果我计划在我的 Mac 上上线网站,我必须计算“.DS_Store”文件!
比“Davy Defaud 的函数”更好的(仅限 PHP 5)替代方案
<?php
function is_empty_dir($dir)
{
if (($files = @scandir($dir)) && count($files) <= 2) {
return true;
}
return false;
}
?>
注意:您应该事先检查 $dir 是否实际上是一个目录,并且它是可读的,因为仅依赖于此,您将假设在这两种情况下您都有一个非空的可读目录。
不幸的是,p dot marzec at bold-sg dot pl 发布的函数不起作用。
更正后的版本是
// 如果文件夹为空或不存在,则返回 true
// 如果文件夹已满,则返回 false
function is_empty_folder($dir) {
if (is_dir($dir)) {
$dl=opendir($dir);
if ($dl) {
while($name = readdir($dl)) {
if (!is_dir("$dir/$name")) { //<--- 在此处更正
return false;
break;
}
}
closedir($dl);
}
return true;
} else return true;
}
<?php
public static function isEmptyDir($dir){
return (($files = @scandir($dir)) && count($files) <= 2);
}
?>
更好;)
使用此函数获取目录内所有文件(包括子目录)
<?php
function scan_Dir($dir) {
$arrfiles = array();
if (is_dir($dir)) {
if ($handle = opendir($dir)) {
chdir($dir);
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (is_dir($file)) {
$arr = scan_Dir($file);
foreach ($arr as $value) {
$arrfiles[] = $dir."/".$value;
}
} else {
$arrfiles[] = $dir."/".$file;
}
}
}
chdir("../");
}
closedir($handle);
}
return $arrfiles;
}
?>