PHP dir() 函数

定义和用法

dir() 函数以面向对象的方式打开一个目录句柄,并返回一个 Directory 类的实例。通过这个实例,可以使用面向对象的方法来遍历目录内容。

注意:dir() 函数返回的是 Directory 类的实例,它提供了 read(), rewind(), close() 三个公共方法。这与 opendir()/readdir()/closedir() 的函数式方法相似,但采用面向对象的方式。

语法

dir(string $directory, ?resource $context = null): Directory|false

参数

参数 描述
directory

必需。要打开的目录路径。

可以是绝对路径或相对路径。

context

可选。流上下文(stream context)资源。

用于指定流的特殊选项,如访问 FTP 或 HTTP 目录时需要。

返回值

返回值 描述
Directory 对象 成功打开目录时返回 Directory 类的实例
FALSE 打开目录失败(目录不存在或没有权限)

Directory 类的方法

方法 描述 对应函数
read() 从目录句柄中读取一个条目 readdir()
rewind() 将目录句柄的指针重置到开头 rewinddir()
close() 关闭目录句柄 closedir()

示例

示例1:基本用法

<?php
// 打开目录
$dirPath = "/tmp";
$dir = dir($dirPath);

// 检查是否成功打开
if ($dir) {
    echo "目录句柄打开成功: " . $dirPath . "<br>";

    // 遍历目录内容
    echo "目录内容:<br>";
    while (false !== ($entry = $dir->read())) {
        echo $entry . "<br>";
    }

    // 关闭目录句柄
    $dir->close();
    echo "目录句柄已关闭";
} else {
    echo "无法打开目录: " . $dirPath;
}
?>

示例2:使用 rewind() 方法

<?php
$dir = dir("/tmp");

if ($dir) {
    echo "第一次遍历:<br>";
    $count1 = 0;
    while (($entry = $dir->read()) !== false && $count1 < 3) {
        echo $entry . "<br>";
        $count1++;
    }

    echo "<br>只显示了前3个条目<br><br>";

    // 重置指针到开头
    $dir->rewind();

    echo "重置后再次遍历:<br>";
    $count2 = 0;
    while (($entry = $dir->read()) !== false && $count2 < 5) {
        echo $entry . "<br>";
        $count2++;
    }

    $dir->close();
}
?>

示例3:过滤目录条目

<?php
/**
 * 列出目录中所有的PHP文件
 * @param string $directory 目录路径
 */
function listPhpFiles($directory) {
    $dir = dir($directory);

    if (!$dir) {
        return false;
    }

    $phpFiles = [];

    while (false !== ($entry = $dir->read())) {
        // 跳过 . 和 ..
        if ($entry == '.' || $entry == '..') {
            continue;
        }

        // 检查是否是PHP文件
        if (pathinfo($entry, PATHINFO_EXTENSION) === 'php') {
            $phpFiles[] = $entry;
        }
    }

    $dir->close();
    return $phpFiles;
}

// 使用示例
$directory = "/var/www/html";
$phpFiles = listPhpFiles($directory);

if ($phpFiles !== false) {
    echo "在 $directory 中找到的PHP文件:<br>";
    if (count($phpFiles) > 0) {
        foreach ($phpFiles as $file) {
            echo "- " . htmlspecialchars($file) . "<br>";
        }
    } else {
        echo "没有找到PHP文件";
    }
} else {
    echo "无法打开目录: $directory";
}
?>

示例4:使用上下文参数

<?php
// 使用上下文参数访问FTP目录
$ftpUrl = "ftp://example.com/public_html/";

// 创建FTP上下文选项
$options = [
    'ftp' => [
        'overwrite' => true,
        'username' => 'your_username',
        'password' => 'your_password'
    ]
];

// 创建流上下文
$context = stream_context_create($options);

// 尝试打开FTP目录
$dir = dir($ftpUrl, $context);

if ($dir) {
    echo "FTP目录内容:<br>";
    while (false !== ($entry = $dir->read())) {
        echo $entry . "<br>";
    }
    $dir->close();
} else {
    echo "无法访问FTP目录";
}
?>

示例5:与 DirectoryIterator 的比较

<?php
// 使用 dir() 函数
echo "使用 dir() 函数:<br>";
$dir1 = dir("/tmp");
if ($dir1) {
    while (false !== ($entry = $dir1->read())) {
        echo $entry . " ";
    }
    $dir1->close();
}
echo "<br><br>";

// 使用 DirectoryIterator 类
echo "使用 DirectoryIterator:<br>";
$iterator = new DirectoryIterator("/tmp");
foreach ($iterator as $fileInfo) {
    echo $fileInfo->getFilename() . " ";
}

echo "<br><br><strong>比较:</strong><br>";
echo "dir() 更简单直接,但功能有限<br>";
echo "DirectoryIterator 提供更多功能(如文件类型检查、文件信息等)";
?>

dir() 与 opendir()/readdir()/closedir() 的比较

特性 dir() 函数 opendir()/readdir()/closedir()
编程风格 面向对象 过程式
返回值 Directory 对象 资源句柄
方法/函数 read(), rewind(), close() 方法 readdir(), rewinddir(), closedir() 函数
错误处理 返回 false 或抛出异常 返回 false 或发出警告
代码可读性 较好(面向对象风格) 一般
向后兼容性 PHP 4+ PHP 4+

Directory 类的内部结构

Directory 类 是一个内置类,它有以下特点:

  • 没有构造函数(通过 dir() 函数实例化)
  • 只有三个公共方法:read(), rewind(), close()
  • 内部包含一个目录句柄资源
  • 当对象被销毁时,会自动调用 close() 方法

最佳实践

  1. 总是检查返回值:dir() 可能返回 false,调用方法前应先检查
  2. 及时关闭目录句柄:虽然对象销毁时会自动关闭,但显式调用 close() 更好
  3. 考虑使用 DirectoryIterator:对于新代码,考虑使用功能更丰富的 DirectoryIterator 或 FilesystemIterator
  4. 过滤特殊条目:遍历时记得过滤 '.' 和 '..' 这两个特殊目录
  5. 错误处理:使用 try-catch 或检查返回值来处理可能的错误

常见错误

错误 原因 解决方法
Warning: dir() expects parameter 1 to be a valid path 目录路径无效或不存在 检查目录路径是否正确,确保目录存在
Fatal error: Call to a member function read() on boolean dir() 返回 false,但尝试调用方法 在调用方法前检查返回值是否为 Directory 对象
无法读取某些文件 权限不足 确保 PHP 进程有读取目录的权限
性能问题 遍历非常大的目录 考虑分批处理或使用更高效的目录遍历方法

相关函数