PHPfile()函数

file() 函数是PHP中用于将整个文件读入数组的内置函数。它读取文件的每一行,并将每一行作为数组的一个元素。这个函数非常适合读取配置文件、日志文件等需要逐行处理的情况。

语法

array file ( string $filename [, int $flags = 0 [, resource $context ]] )

参数说明

参数 描述 是否必需 默认值
filename 要读取的文件路径 -
flags 可选。可以使用以下一个或多个常量:
  • FILE_USE_INCLUDE_PATH - 在include_path中查找文件
  • FILE_IGNORE_NEW_LINES - 忽略每行末尾的换行符
  • FILE_SKIP_EMPTY_LINES - 跳过空行
0
context 可选。文件上下文资源,由stream_context_create()创建 null

返回值

  • 成功时返回包含文件行的数组。
  • 失败时返回 FALSE
  • 数组的每个元素对应文件中的一行,包括换行符(除非使用FILE_IGNORE_NEW_LINES标志)。

注意事项

  • file()函数会将整个文件加载到内存中,因此不适合处理非常大的文件。
  • 每行末尾的换行符会保留,除非使用FILE_IGNORE_NEW_LINES标志。
  • 如果文件不存在或无法读取,函数会返回FALSE并生成一个E_WARNING级别的错误。
  • 可以使用@错误控制运算符来抑制错误信息。

示例代码

示例1:基本使用 - 读取文件到数组
<?php
// 读取文件,每行作为数组的一个元素
$lines = file('data.txt');

if ($lines !== false) {
    foreach ($lines as $line_num => $line) {
        echo "行 #{$line_num} : " . htmlspecialchars($line) . "<br>\n";
    }
} else {
    echo "无法读取文件";
}
?>
示例2:使用标志参数
<?php
// 读取文件,忽略换行符并跳过空行
$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

if ($lines !== false) {
    echo "文件共有 " . count($lines) . " 行非空内容:<br>\n";
    foreach ($lines as $line) {
        echo htmlspecialchars($line) . "<br>\n";
    }
}
?>
示例3:处理大文件的替代方案
注意:file()会将整个文件加载到内存,对于大文件建议使用fgets()逐行读取。
<?php
// 使用file() - 适合小文件
function readSmallFile($filename) {
    return file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
}

// 使用fgets()逐行读取 - 适合大文件
function readLargeFile($filename) {
    $lines = [];
    $file = fopen($filename, 'r');
    if ($file) {
        while (($line = fgets($file)) !== false) {
            $line = rtrim($line); // 移除换行符
            if ($line !== '') {
                $lines[] = $line;
            }
        }
        fclose($file);
    }
    return $lines;
}

// 根据文件大小选择方法
$filename = 'data.txt';
if (filesize($filename) < 1024 * 1024) { // 小于1MB
    $lines = readSmallFile($filename);
} else {
    $lines = readLargeFile($filename);
}

echo "读取了 " . count($lines) . " 行数据";
?>
示例4:读取CSV文件
<?php
// 读取CSV文件并解析每行
$csv_lines = file('data.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$data = [];

if ($csv_lines !== false) {
    foreach ($csv_lines as $line) {
        // 将CSV行拆分为数组
        $row = str_getcsv($line);
        $data[] = $row;
    }
}

echo "<pre>";
print_r($data);
echo "</pre>";
?>
示例5:读取远程文件
<?php
// 使用stream_context_create创建上下文
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => "User-Agent: MyPHPApp\r\n"
    ]
]);

// 读取远程文件
$url = 'https://example.com/data.txt';
$lines = @file($url, FILE_IGNORE_NEW_LINES, $context);

if ($lines !== false) {
    echo "从远程URL读取了 " . count($lines) . " 行数据";
} else {
    echo "无法读取远程文件";
}
?>
示例6:读取INI配置文件
<?php
// 读取配置文件
$config_lines = file('config.ini', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$config = [];

if ($config_lines !== false) {
    foreach ($config_lines as $line) {
        // 跳过注释行
        if (strpos(trim($line), ';') === 0 || strpos(trim($line), '#') === 0) {
            continue;
        }

        // 解析键值对
        if (strpos($line, '=') !== false) {
            list($key, $value) = explode('=', $line, 2);
            $config[trim($key)] = trim($value);
        }
    }
}

echo "数据库主机: " . ($config['db_host'] ?? '未设置');
?>

与类似函数的比较

函数 描述 适用场景
file() 将整个文件读入数组 小文件、配置文件、需要随机访问行
file_get_contents() 将整个文件读入字符串 小文件、需要整体处理的内容
fgets() 逐行读取文件 大文件、内存敏感的场景
readfile() 读取文件并输出到缓冲区 直接输出文件内容到浏览器

性能优化建议

最佳实践
  • 对于小于1MB的文件,使用file()是合适的。
  • 对于大文件,使用fgets()逐行读取。
  • 使用FILE_IGNORE_NEW_LINES标志可以避免后续处理换行符。
  • 读取远程文件时,设置适当的超时和上下文选项。
  • 使用@file()抑制错误,但更好的做法是检查文件是否存在和可读。
完整示例:安全地读取文件
<?php
function safeFileRead($filename, $flags = 0) {
    // 检查文件是否存在
    if (!file_exists($filename)) {
        throw new Exception("文件不存在: $filename");
    }

    // 检查文件是否可读
    if (!is_readable($filename)) {
        throw new Exception("文件不可读: $filename");
    }

    // 检查文件大小(限制为10MB)
    $max_size = 10 * 1024 * 1024; // 10MB
    if (filesize($filename) > $max_size) {
        throw new Exception("文件过大,最大支持10MB");
    }

    // 读取文件
    $content = file($filename, $flags);

    if ($content === false) {
        throw new Exception("读取文件失败: $filename");
    }

    return $content;
}

// 使用示例
try {
    $lines = safeFileRead('data.txt', FILE_IGNORE_NEW_LINES);
    echo "成功读取 " . count($lines) . " 行数据";
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>