news 2026/6/2 8:40:54

PHP文件系统与目录操作全面指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP文件系统与目录操作全面指南

PHP文件系统与目录操作全面指南

文件操作在PHP里是用得很多的功能。从简单的文件读写到目录遍历,PHP提供了丰富的函数。今天就把这些内容都梳理一遍。

最基本的文件读写函数是file_get_contents和file_put_contents,一条语句完成整个操作。

```php
// 写入文件
file_put_contents('/tmp/test.txt', "Hello PHP!\n");
file_put_contents('/tmp/test.txt', "追加内容\n", FILE_APPEND);

// 读取文件
$content = file_get_contents('/tmp/test.txt');
echo $content;

// Lock_EX防止并发写入
file_put_contents('/tmp/log.txt', "日志行\n", FILE_APPEND | LOCK_EX);

// JSON配置文件的读写
$config = [
'database' => [
'host' => 'localhost',
'port' => 3306,
'name' => 'test',
],
'app' => [
'debug' => true,
'timezone' => 'Asia/Shanghai',
],
];

file_put_contents('/tmp/config.json', json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$loaded = json_decode(file_get_contents('/tmp/config.json'), true);
echo "数据库主机: {$loaded['database']['host']}\n";
?>
```

逐行处理大文件用fopen+fgets,避免一次性加载到内存。

```php
// 逐行读取大文件
function processLargeFile(string $path, callable $lineCallback): void
{
$handle = fopen($path, 'r');
if ($handle === false) {
throw new RuntimeException("无法打开文件: $path");
}

$lineNumber = 0;
while (($line = fgets($handle)) !== false) {
$lineNumber++;
$line = trim($line);
if ($line !== '') {
$lineCallback($lineNumber, $line);
}
}

fclose($handle);
}

// 写入大文件
function writeLargeFile(string $path, array $lines): void
{
$handle = fopen($path, 'w');
if ($handle === false) {
throw new RuntimeException("无法写入文件: $path");
}

foreach ($lines as $line) {
fwrite($handle, $line . "\n");
}

fclose($handle);
}

// CSV文件处理
function readCsv(string $path, bool $hasHeader = true): array
{
$handle = fopen($path, 'r');
if ($handle === false) {
throw new RuntimeException("无法打开CSV: $path");
}

$headers = [];
$data = [];
$rowIndex = 0;

while (($row = fgetcsv($handle)) !== false) {
if ($hasHeader && $rowIndex === 0) {
$headers = $row;
$rowIndex++;
continue;
}

if ($hasHeader && !empty($headers)) {
$data[] = array_combine($headers, $row);
} else {
$data[] = $row;
}
$rowIndex++;
}

fclose($handle);
return $data;
}

function writeCsv(string $path, array $data, ?array $headers = null): void
{
$handle = fopen($path, 'w');
if ($handle === false) {
throw new RuntimeException("无法写入CSV: $path");
}

if ($headers !== null) {
fputcsv($handle, $headers);
}

foreach ($data as $row) {
fputcsv($handle, $row);
}

fclose($handle);
}

// CSV使用示例
$users = [
['name' => '张三', 'email' => 'zhangsan@test.com', 'age' => 28],
['name' => '李四', 'email' => 'lisi@test.com', 'age' => 35],
];
writeCsv('/tmp/users.csv', $users, ['name', 'email', 'age']);
$imported = readCsv('/tmp/users.csv');
print_r($imported);
?>
```

目录操作包括遍历、创建、删除等。

```php
// 创建目录
mkdir('/tmp/mydir/subdir', 0755, true); // true表示递归创建

// 删除目录(必须为空)
rmdir('/tmp/emptydir');

// 递归删除目录
function removeDirectory(string $path): void
{
if (!is_dir($path)) {
return;
}

$items = scandir($path);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$fullPath = "$path/$item";
if (is_dir($fullPath)) {
removeDirectory($fullPath);
} else {
unlink($fullPath);
}
}
rmdir($path);
}

// 遍历目录
function scanDirectory(string $path, string $prefix = ''): void
{
$items = scandir($path);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;

$fullPath = "$path/$item";
if (is_dir($fullPath)) {
echo "$prefix📁 $item/\n";
scanDirectory($fullPath, "$prefix ");
} else {
$size = filesize($fullPath);
$sizeStr = $size > 1024 ? round($size / 1024, 1) . 'KB' : $size . 'B';
echo "$prefix📄 $item ($sizeStr)\n";
}
}
}

mkdir('/tmp/testdir', 0755, true);
file_put_contents('/tmp/testdir/a.txt', '内容A');
file_put_contents('/tmp/testdir/b.txt', '内容B');
mkdir('/tmp/testdir/sub', 0755, true);
file_put_contents('/tmp/testdir/sub/c.txt', '内容C');
scanDirectory('/tmp/testdir');
?>
```

文件信息查询和权限操作。

```php
$path = '/tmp/test.txt';
file_put_contents($path, "测试文件内容");

echo "文件名: " . basename($path) . "\n";
echo "目录: " . dirname($path) . "\n";
echo "扩展名: " . pathinfo($path, PATHINFO_EXTENSION) . "\n";
echo "大小: " . filesize($path) . "字节\n";
echo "创建时间: " . date('Y-m-d H:i:s', filectime($path)) . "\n";
echo "修改时间: " . date('Y-m-d H:i:s', filemtime($path)) . "\n";
echo "访问时间: " . date('Y-m-d H:i:s', fileatime($path)) . "\n";
echo "可读: " . (is_readable($path) ? '是' : '否') . "\n";
echo "可写: " . (is_writable($path) ? '是' : '否') . "\n";
echo "文件: " . (is_file($path) ? '是' : '否') . "\n";

// 文件权限
echo "权限: " . substr(sprintf('%o', fileperms($path)), -4) . "\n";
chmod($path, 0644); // 修改权限

// 文件操作
copy($path, '/tmp/copy.txt');
rename('/tmp/copy.txt', '/tmp/renamed.txt');
unlink('/tmp/renamed.txt');
?>
```

临时文件在PHP中用于存储临时数据。

```php
// 创建临时文件
$tempFile = tmpfile();
fwrite($tempFile, "临时数据");
// 脚本结束或fclose时自动删除

// 获取临时文件路径
$tempPath = tempnam(sys_get_temp_dir(), 'php_');
file_put_contents($tempPath, "数据");
echo "临时文件: $tempPath\n";
unlink($tempPath);

// 流式处理
$stream = fopen('php://temp', 'r+');
fwrite($stream, "流式数据");
rewind($stream);
echo fread($stream, 1024) . "\n";
fclose($stream);
?>
```

锁定机制防止并发写入问题。

```php
// 文件锁定
$fp = fopen('/tmp/locktest.txt', 'a+');

// 获取独占锁
if (flock($fp, LOCK_EX)) {
fwrite($fp, "写入数据\n");
flock($fp, LOCK_UN); // 释放锁
} else {
echo "无法获取文件锁\n";
}

fclose($fp);

// 非阻塞锁
$fp = fopen('/tmp/locktest.txt', 'a+');
if (flock($fp, LOCK_EX | LOCK_NB)) {
fwrite($fp, "非阻塞写入\n");
flock($fp, LOCK_UN);
} else {
echo "文件被锁定,跳过\n";
}
fclose($fp);
?>
```

PHP的文件函数用起来方便,但也有些需要注意的地方。file_get_contents会把整个文件读入内存,几百兆的大文件不能这么搞。写文件时考虑文件锁避免并发写入冲突。上传文件必须用move_uploaded_file不能用copy,因为有安全检查。这些细节注意到了,文件操作就不会出问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 8:40:53

别再只装WebGoat了!WebWolf靶场实战指南:从环境配置到第一个XSS攻击

WebWolf靶场实战指南:从环境配置到第一个XSS攻击 在网络安全学习领域,WebGoat早已成为入门者的经典选择。但鲜为人知的是,它的姊妹项目WebWolf才是真正能让你理解攻击者思维的利器。本文将带你深入探索这个被低估的靶场,从零开始构…

作者头像 李华
网站建设 2026/6/2 8:40:38

从调和分割到极点极线:用GeoGebra动态演示理解二次曲线的奇妙几何

从调和分割到极点极线:用GeoGebra动态演示理解二次曲线的奇妙几何 数学之美往往隐藏在抽象的符号背后,而动态几何软件正是打开这扇神秘之门的钥匙。想象一下,当你拖动屏幕上的一个点,就能实时看到与之关联的直线如何舞动&#xff…

作者头像 李华
网站建设 2026/6/2 8:40:36

从15分钟到90秒:多阶段镜像构建与缓存重用加速Docker CI/CD流水线

从15分钟到90秒:多阶段镜像构建与缓存重用加速Docker CI/CD流水线上个月接手了一个Java微服务项目的CI/CD优化任务。开发抱怨每次代码提交后等镜像构建要15分钟,别说快速迭代了,改个日志级别都要等半天。 Docker镜像构建慢,根本原…

作者头像 李华
网站建设 2026/6/2 8:40:24

用手机BLE遥控你的FOC电机:基于ESP32+STM32F405的双核通信实战

用手机BLE遥控你的FOC电机:基于ESP32STM32F405的双核通信实战 在智能硬件开发领域,电机控制与无线通信的结合正成为创新热点。想象一下,通过手机App就能实时调整工业设备的电机参数,或者用蓝牙遥控智能家居中的电动窗帘——这种无…

作者头像 李华
网站建设 2026/6/2 8:40:14

UE5新手必看:用Niagara粒子系统+一张序列图,5分钟搞定动态火焰特效

UE5动态火焰特效实战:Niagara粒子系统极简入门指南火焰特效是游戏开发中最常见的视觉元素之一,但很多初学者在面对UE5的Niagara粒子系统时容易陷入细节迷宫。本文将带你用一张序列帧图片,通过Niagara最核心的5个模块,在5分钟内实现…

作者头像 李华