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 | LOCK_EX);
$content = file_get_contents('/tmp/test.txt');
echo $content;
file_put_contents('/tmp/config.json', json_encode([
'database' => ['host' => 'localhost', 'port' => 3306],
'app' => ['name' => 'MyApp'],
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
?>
```
逐行处理大文件用fopen+fgets,避免一次性加载到内存。
```php
function processLargeFile(string $path): void
{
$handle = fopen($path, 'r');
if ($handle === false) {
throw new RuntimeException("无法打开文件");
}
$lineNumber = 0;
while (($line = fgets($handle)) !== false) {
$lineNumber++;
$line = trim($line);
if ($line !== '') {
echo "{$lineNumber}: {$line}\n";
}
}
fclose($handle);
}
file_put_contents('/tmp/large.txt', implode("\n", range(1, 100)));
processLargeFile('/tmp/large.txt');
?>
```
目录操作包括创建、遍历和删除。
```php
mkdir('/tmp/mydir/subdir', 0755, true);
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);
echo "$prefix📄 $item ($size字节)\n";
}
}
}
mkdir('/tmp/demo', 0755, true);
file_put_contents('/tmp/demo/file1.txt', '内容1');
file_put_contents('/tmp/demo/file2.txt', '内容2');
mkdir('/tmp/demo/sub', 0755, true);
file_put_contents('/tmp/demo/sub/file3.txt', '内容3');
scanDirectory('/tmp/demo');
?>
```
文件信息和权限操作。
```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', filemtime($path)) . "\n";
echo "可读: " . (is_readable($path) ? '是' : '否') . "\n";
echo "可写: " . (is_writable($path) ? '是' : '否') . "\n";
copy($path, '/tmp/copy.txt');
rename('/tmp/copy.txt', '/tmp/renamed.txt');
unlink('/tmp/renamed.txt');
?>
```
CSV文件处理在数据导入导出时很常用。
```php
function readCsv(string $path, bool $hasHeader = true): array
{
$handle = fopen($path, 'r');
$headers = [];
$data = [];
$rowIndex = 0;
while (($row = fgetcsv($handle)) !== false) {
if ($hasHeader && $rowIndex === 0) {
$headers = $row;
$rowIndex++;
continue;
}
$data[] = $hasHeader && !empty($headers) ? array_combine($headers, $row) : $row;
$rowIndex++;
}
fclose($handle);
return $data;
}
function writeCsv(string $path, array $data, ?array $headers = null): void
{
$handle = fopen($path, 'w');
if ($headers !== null) fputcsv($handle, $headers);
foreach ($data as $row) fputcsv($handle, $row);
fclose($handle);
}
writeCsv('/tmp/users.csv', [
['name' => '张三', 'email' => 'zhangsan@test.com'],
], ['name', 'email']);
$imported = readCsv('/tmp/users.csv');
print_r($imported);
?>
```
PHP的文件用起来方便,但大文件要注意内存。file_get_contents会读入整个文件,几百兆的文件不能这么搞。写文件时考虑文件锁避免并发写入冲突。上传文件必须用move_uploaded_file不能用copy。
PHP文件系统操作与目录遍历