本文目录导读:

我来详细介绍 PHP 项目目录结构管理和 scandir 函数的使用。
常见 PHP 项目目录结构
基础项目结构
my-project/
├── public/ # 公共访问目录(Document Root)
│ ├── index.php
│ ├── css/
│ ├── js/
│ └── images/
├── src/ # 源代码
│ ├── Controllers/
│ ├── Models/
│ ├── Views/
│ └── Helpers/
├── config/ # 配置文件
│ ├── database.php
│ └── app.php
├── vendor/ # 第三方库(Composer)
├── logs/ # 日志文件
├── uploads/ # 上传文件
├── cache/ # 缓存
├── tests/ # 测试文件
├── composer.json
├── .env # 环境变量
└── .gitignore
框架项目结构示例(Laravel)
laravel-project/
├── app/
│ ├── Http/
│ │ └── Controllers/
│ ├── Models/
│ └── Providers/
├── bootstrap/
├── config/
├── database/
│ ├── migrations/
│ └── seeds/
├── public/
├── resources/
│ ├── views/
│ └── lang/
├── routes/
├── storage/
├── tests/
└── vendor/
scandir() 函数详解
基本语法
scandir(string $directory, int $sorting_order = SCANDIR_SORT_ASCENDING, ?resource $context = null): array|false
基本用法
// 扫描当前目录
$files = scandir('./');
print_r($files);
// 扫描指定目录
$files = scandir('/var/www/html/project');
print_r($files);
排序选项
// 默认升序排序
$files_asc = scandir('./uploads', SCANDIR_SORT_ASCENDING);
// 降序排序
$files_desc = scandir('./uploads', SCANDIR_SORT_DESCENDING);
// 不排序
$files_none = scandir('./uploads', SCANDIR_SORT_NONE);
实用示例
获取目录中所有文件(排除 . 和 ..)
function getDirectoryFiles(string $dir): array {
$files = scandir($dir);
// 过滤掉 . 和 ..
$files = array_diff($files, ['.', '..']);
// 重新索引数组
return array_values($files);
}
// 使用
$files = getDirectoryFiles('./uploads');
print_r($files);
递归扫描目录
function scanDirectoryRecursive(string $dir): array {
$result = [];
$files = scandir($dir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path)) {
$result[$file] = scanDirectoryRecursive($path);
} else {
$result[] = $file;
}
}
return $result;
}
// 使用
$structure = scanDirectoryRecursive('./project');
print_r($structure);
按文件类型筛选
function getFilesByExtension(string $dir, string $extension): array {
$files = scandir($dir);
$filtered = [];
foreach ($files as $file) {
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_file($path) && pathinfo($file, PATHINFO_EXTENSION) === $extension) {
$filtered[] = $file;
}
}
return $filtered;
}
// 获取所有 PHP 文件
$php_files = getFilesByExtension('./src', 'php');
// 获取所有图片文件
$images = getFilesByExtension('./uploads', 'jpg');
安全和错误处理
function safeScanDir(string $dir): array {
// 检查目录是否存在
if (!is_dir($dir)) {
throw new InvalidArgumentException("目录不存在: $dir");
}
// 检查读取权限
if (!is_readable($dir)) {
throw new RuntimeException("无法读取目录: $dir");
}
$files = scandir($dir);
if ($files === false) {
throw new RuntimeException("扫描目录失败: $dir");
}
return array_diff($files, ['.', '..']);
}
try {
$files = safeScanDir('./uploads');
print_r($files);
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
文件信息增强版
function getDetailedFileInfo(string $dir): array {
$files = scandir($dir);
$details = [];
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
$details[] = [
'name' => $file,
'path' => $path,
'type' => is_dir($path) ? 'directory' : 'file',
'size' => is_file($path) ? filesize($path) : 0,
'modified' => filemtime($path),
'extension' => pathinfo($file, PATHINFO_EXTENSION),
'permissions' => substr(sprintf('%o', fileperms($path)), -4)
];
}
return $details;
}
// 使用
$file_info = getDetailedFileInfo('./project');
print_r($file_info);
性能优化建议
// 对于大目录,使用 DirectoryIterator
function efficientScanDir(string $dir): array {
$files = [];
$iterator = new DirectoryIterator($dir);
foreach ($iterator as $fileInfo) {
if ($fileInfo->isDot()) continue;
$files[] = $fileInfo->getFilename();
}
return $files;
}
// 使用 Glob 进行模式匹配
function scanDirWithPattern(string $pattern): array {
return glob($pattern);
}
// 示例
$php_files = scanDirWithPattern('./src/**/*.php');
$json_files = scanDirWithPattern('./config/*.json');
实际应用场景
文件管理器
class FileManager {
private string $basePath;
public function __construct(string $basePath) {
$this->basePath = rtrim($basePath, '/');
}
public function listDirectory(string $subDir = ''): array {
$fullPath = $this->basePath . ($subDir ? '/' . $subDir : '');
if (!is_dir($fullPath)) {
return ['error' => '目录不存在'];
}
$files = scandir($fullPath);
$items = [];
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$path = $fullPath . '/' . $file;
$items[] = [
'name' => $file,
'type' => is_dir($path) ? 'folder' : 'file',
'size' => is_file($path) ? filesize($path) : null,
'modified' => date('Y-m-d H:i:s', filemtime($path))
];
}
return $items;
}
}
// 使用
$fm = new FileManager('/var/www/uploads');
$files = $fm->listDirectory('images');
这个指南涵盖了 PHP 项目目录结构和 scandir 函数的主要用法,根据具体需求,你可以组合使用这些方法来处理文件和目录操作。