file

(PHP 4, PHP 5, PHP 7, PHP 8)

file将整个文件读入数组

描述

file(string $filename, int $flags = 0, ?resource $context = null): array|false

将整个文件读入数组。

注意:

您可以使用 file_get_contents() 将文件内容作为字符串返回。

参数

filename

文件路径。

提示

如果启用了 fopen 包装器,则可以使用 URL 作为此函数的文件名。有关如何指定文件名的更多详细信息,请参见 fopen()。有关各种包装器的功能、使用说明以及它们可能提供的任何预定义变量的信息,请参见 支持的协议和包装器

flags

可选参数 flags 可以是以下常量之一或多个

FILE_USE_INCLUDE_PATH
include_path 中搜索文件。
FILE_IGNORE_NEW_LINES
省略每个数组元素末尾的换行符
FILE_SKIP_EMPTY_LINES
跳过空行
FILE_NO_DEFAULT_CONTEXT
不要使用默认上下文

context

上下文流 resource

返回值

返回一个包含文件内容的数组。数组的每个元素对应于文件中的每一行,换行符仍然保留。如果失败,file() 返回 false

注意:

结果数组中的每一行都将包含行尾,除非使用 FILE_IGNORE_NEW_LINES

注意: 如果 PHP 在读取在 Macintosh 计算机上或由其创建的文件时没有正确识别行尾,则启用 auto_detect_line_endings 运行时配置选项可能有助于解决此问题。

错误/异常

如果文件不存在,则会发出 E_WARNING 级别的错误。

示例

示例 #1 file() 示例

<?php
// 将文件读入数组。在此示例中,我们将通过 HTTP 获取 URL 的 HTML 源代码。
$lines = file('http://www.example.com/');

// 遍历数组,将 HTML 源代码显示为 HTML 源代码;并显示行号。
foreach ($lines as $line_num => $line) {
echo
"Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}

// 使用可选的 flags 参数
$trimmed = file('somefile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
?>

备注

警告

在使用 SSL 时,Microsoft IIS 会通过在未发送 close_notify 指示的情况下关闭连接来违反协议。当您到达数据末尾时,PHP 会将其报告为“SSL:致命协议错误”。为了解决此问题,应将 error_reporting 的值降低到不包含警告的级别。当您使用 https:// 包装器打开流时,PHP 可以检测到有缺陷的 IIS 服务器软件,并将抑制警告。当使用 fsockopen() 创建 ssl:// 套接字时,开发人员负责检测和抑制此警告。

参见

添加笔记

用户贡献的笔记 15 笔记

31
Martin K.
10 年前
如果您正在读取的文件是 CSV 格式,请不要使用 file(),请使用 fgetcsv()。file() 将根据它找到的每个换行符拆分文件,即使换行符出现在字段内(即引号内)。
22
bingo at dingo dot com
10 年前
要写入文件的所有行,换句话说,要逐行读取文件,您可以这样编写代码
<?php
$names
=file('name.txt');
// 检查行数
echo count($names).'<br>';
foreach(
$names as $name)
{
echo
$name.'<br>';
}
?>

此示例非常基础,可以帮助您理解它的工作原理。希望它能帮助许多初学者。

此致,
Bingo
15
d basin
14 年前
这可能很明显,但我花了很长时间才弄清楚我做错了什么。所以我想分享一下。我在我的“c:\”驱动器上有一个文件。如何用 file() 打开它?

不要忘记反斜杠是特殊的,您必须对其进行“转义”,即“\\”

<?php

$lines
= file("C:\\Documents and Settings\\myfile.txt");

foreach(
$lines as $line)
{
echo(
$line);
}

?>

希望这有帮助……
9
twichi at web dot de
12 年前
从 CSV 数据(文件)读入具有命名键的数组

… 有或没有第一行 = 标题(键)
(查看函数调用的第四个参数是 true / false)

<?php
// --------------------------------------------------------------

function csv_in_array($url,$delm=";",$encl="\"",$head=false) {

$csvxrow = file($url); // ---- csv rows to array ----

$csvxrow[0] = chop($csvxrow[0]);
$csvxrow[0] = str_replace($encl,'',$csvxrow[0]);
$keydata = explode($delm,$csvxrow[0]);
$keynumb = count($keydata);

if (
$head === true) {
$anzdata = count($csvxrow);
$z=0;
for(
$x=1; $x<$anzdata; $x++) {
$csvxrow[$x] = chop($csvxrow[$x]);
$csvxrow[$x] = str_replace($encl,'',$csvxrow[$x]);
$csv_data[$x] = explode($delm,$csvxrow[$x]);
$i=0;
foreach(
$keydata as $key) {
$out[$z][$key] = $csv_data[$x][$i];
$i++;
}
$z++;
}
}
else {
$i=0;
foreach(
$csvxrow as $item) {
$item = chop($item);
$item = str_replace($encl,'',$item);
$csv_data = explode($delm,$item);
for (
$y=0; $y<$keynumb; $y++) {
$out[$i][$y] = $csv_data[$y];
}
$i++;
}
}

return
$out;
}

// --------------------------------------------------------------

?>

使用 4 个参数调用函数

(1) = 包含 CSV 数据的文件(URL 或字符串)
(2) = 列分隔符(例如:; 或 | 或 , ...)
(3) = 值包围符(例如:' 或 " 或 ^ 或 ...)
(4) = 是否包含第一行作为标题(true/false)

<?php

// ----- 调用 ------
$csvdata = csv_in_array( $yourcsvfile, ";", "\"", true );
// -----------------

// ----- 查看 ------
echo "<pre>\r\n";
print_r($csvdata);
echo
"</pre>\r\n";
// -----------------

?>

PS:也可以参考:https://php.net/manual/de/function.fgetcsv.php 将 CSV 数据读入数组
... 以及其他文件处理方法

^
0
radler63 at hotmail dot com
5 年前
我的经验是,如果文件发生了变化,函数 file 会使用缓存内容。
-2
renanlazarotto at gmail dot com
3 年前
请注意,使用 file() 来计数行可能会导致服务器出现 OOM,因为它会将所有行分配到一个数组中。

如果您处理的是可能包含数千行的文件,SplFileObject 可能是一个更好的选择,只需稍作修改就可以得到相同的结果。
-4
sheldon at hyperlinked dot com
5 年前
从 PHP 5.6 开始,如果引用的是没有有效 SSL 证书的源 URL,则 file()、file_get_contents() 和 fopen() 函数将返回 false。可能在您的开发环境中经常遇到这种情况,这会让您抓狂。

您需要创建一个流上下文,并将其作为参数提供给各种文件操作,告诉它忽略无效的 SSL 证书。

$args = array("ssl"=>array("verify_peer"=>false,"verify_peer_name"=>false),"http"=>array('timeout' => 60, 'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/3.0.0.1'));

$context = stream_context_create($args);
$httpfile = file($url, false, $context);
-11
Reversed: moc dot liamg at senroc dot werdna
17 年前
此说明适用于 Windows 下的 PHP 5.1.6(尽管可能适用于其他版本)。

看起来 'FILE_IGNORE_NEW_LINES' 标志在读取 Windows 风格的文本文件(即行以 '\r\n' 结尾的文件)时不能正确删除换行符。

解决方案:始终优先使用 'rtrim()' 而不是 'FILE_IGNORE_NEW_LINES'。
-20
匿名
10 年前
(“file() 处理 UTF-16 存在问题”是错误的。此内容已更新。
前者可能会错过字符串的最后一行。)

file() 在处理
带 BOM 或不带 BOM 的 UTF-16 时似乎存在问题。

file() 可能会将 "\n"=LF (0A) 视为行结束符。
因此,不仅 "000A",而且 "010A, 020A,...,FE0A, FF0A,..."
都被视为行结束符。

此外,file() 在 UTF-16LE 中会导致严重问题。
file() 会丢失第一个 "0A"("0A00" 的前半部分)!
并且下一行以 "00" 开头("0A00" 的剩余部分)。
因此,第一行 "0A" 之后的行完全不同。

为了避免这种现象,
例如,在(php_script:UTF-8,file:UTF-16,行结束符为 "\r\n")的情况下,

<?php

mb_regex_encoding
('UTF-16'); // 帮助 mb_ereg_..() 正确工作
$str = file_get_contents($file_path);
$to_encoding = 'UTF-16'; // 字符串的编码
$from_encoding = 'UTF-8'; // PHP_script 的编码
$pattern1 = mb_convert_encoding('[^\r]*\r\n', $to_encoding, $from_encoding);
mb_ereg_search_init($str, $pattern1);
while (
$res = mb_ereg_search_regs()) {
$file[] = $res[0];
}
$pattern2 = mb_convert_encoding('\A.*\r\n(.*)\z', $to_encoding, $from_encoding);
mb_ereg($pattern2, $str, $match);
$file[] = $match[1];

?>

而不是
$file = file($file_path);

如果行结束符为 "\n",
$pattern1 = mb_convert_encoding('[^\n]*\n', $to_encoding, $from_encoding);
-21
justin at visunet dot ie
21 年前
注意:现在 file() 是二进制安全的,它比以前“慢”得多。如果您打算读取大型文件,使用 fgets() 而不是 file() 可能会有所帮助。例如

<?php
$fd
= fopen ("log_file.txt", "r");
while (!
feof ($fd))
{
$buffer = fgets($fd, 4096);
$lines[] = $buffer;
}
fclose ($fd);
?>

结果数组是 $lines。

我测试了一个包含 200,000 行的文件。使用 fgets() 耗时几秒,而使用 file() 则耗时几分钟。
-16
vbchris at gmail dot com
16 年前
如果您在尝试使用 file() 或 fopen() 访问另一个服务器上的文件时收到“无法打开流:权限被拒绝”错误。检查您的主机是否实施了任何阻止出站连接的防火墙限制。我的主机 Aplus.net 就是这种情况。
-19
lanresmith
7 年前
使用 if ( file(name.txt) ) 可能不足以测试文件是否已成功打开以供读取,因为文件可能是空的,在这种情况下返回的数组为空,因此请使用 !== 进行测试。例如:

$file_array = file('test.txt'); // 一个空文件

echo '<pre>';
if ( $file_array ) {
# 代码...
echo "成功\n";
} else {
# 代码...
echo "失败\n"; // 执行
}

if ( $file_array !== false ) {
# 代码...
echo "成功\n"; // 执行
} else {
# 代码...
echo "失败\n";
}
echo '</pre>';

结果
失败
成功
-20
jon+spamcheck at phpsitesolutions dot com
16 年前
一位用户建议始终使用 rtrim,因为行尾与具有与服务器行尾不同的 EOL 的文件存在冲突。

但是,使用 rtrim 及其默认字符替换是一个糟糕的解决方案,因为它除了 '\r' 和 '\n' 字符外,还会删除所有空白。

以下是使用 rtrim 的一个好的解决方案

<?php
$line
= rtrim($line, "\r\n") . PHP_EOL;
?>

这仅删除 EOL 字符,并用服务器的 EOL 字符替换,从而使 preg_* 在匹配 EOL ($) 时正常工作。
-22
marco dot remy at aol dot com
10 年前
这是我的 CSV 转换器
支持标题并修剪所有字段
注意:标题不能为空!

<?php

function csv2array($file, $delim = ';', $encl = '"', $header = false) {

# 文件不存在
if(!file_exists($file))
return
false;

# 将文件行读取到数组中
$file_lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

# 空文件
if($file_lines === array())
return
NULL;

# 如果需要,读取标题
if($header === true) {
$line_header = array_shift($file_lines);
$array_header = array_map('trim', str_getcsv($line_header, $delim, $encl));
}

$out = NULL;

# 现在逐行(字符串)
foreach ($file_lines as $line) {
# 跳过空行
if(trim($line) === '')
continue;

# 将行转换为数组
$array_fields = array_map('trim', str_getcsv($line, $delim, $encl));

# 如果存在标题,将标题和字段组合为键 => 值
if($header === true)
$out[] = array_combine ($array_header, $array_fields);
else
$out[] = $array_fields;
}

return
$out;
}
?>
-46
info at carstanje dot com
17 年前
使用 file() 读取大于 10 Mb 的大型文本文件会出现问题,因此您应该改为使用此方法。它速度慢得多,但工作正常。$lines 将返回包含所有行的数组。

<?php
$handle
= @fopen('yourfile...', "r");
if (
$handle) {
while (!
feof($handle)) {
$lines[] = fgets($handle, 4096);
}
fclose($handle);
}
?>
To Top