PHP Conference Japan 2024

file_get_contents

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

file_get_contents将整个文件读取到字符串中

描述

file_get_contents(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null,
    int $offset = 0,
    ?int $length = null
): string|false

此函数类似于 file(),不同之处在于 file_get_contents() 将文件以 string 类型返回,从指定的 offset 开始,最多读取 length 个字节。失败时,file_get_contents() 将返回 false

file_get_contents() 是将文件内容读取到字符串的首选方法。如果您的操作系统支持,它将使用内存映射技术来提高性能。

注意:

如果您打开包含特殊字符(例如空格)的 URI,则需要使用 urlencode() 对 URI 进行编码。

参数

filename

要读取的文件名。

use_include_path

注意:

可以使用 FILE_USE_INCLUDE_PATH 常量来触发 include path 搜索。如果启用了 严格类型,则这是不可能的,因为 FILE_USE_INCLUDE_PATH 是一个 int。请改用 true

context

使用 stream_context_create() 创建的有效上下文资源。如果您不需要使用自定义上下文,则可以使用 null 跳过此参数。

offset

读取在原始流中开始的位置。负偏移量从流的末尾计数。

远程文件不支持寻址(offset)。尝试在非本地文件上进行寻址可能会在小偏移量下工作,但这不可预测,因为它是在缓冲流上工作的。

length

读取数据的最大长度。默认值是读取到文件结尾。请注意,此参数适用于过滤器处理的流。

返回值

该函数返回读取的数据或失败时的 false

警告

此函数可能会返回布尔值 false,但也可能返回计算结果为 false 的非布尔值。请阅读有关 布尔值 的部分以了解更多信息。使用 === 运算符 来测试此函数的返回值。

错误/异常

如果找不到 filenamelength 小于零,或者在流中搜索指定的 offset 失败,则会生成 E_WARNING 级别的错误。

当在目录上调用 file_get_contents() 时,在 Windows 上会生成 E_WARNING 级别的错误,从 PHP 7.4 开始,其他操作系统上也会生成此错误。

变更日志

版本 描述
8.0.0 length 现在可以为空。
7.1.0 已添加对负 offset 的支持。

示例

示例 #1 获取并输出网站主页的源代码

<?php
$homepage
= file_get_contents('http://www.example.com/');
echo
$homepage;
?>

示例 #2 在 include_path 中搜索

<?php
// 如果启用了严格类型,即 declare(strict_types=1);
$file = file_get_contents('./people.txt', true);
// 否则
$file = file_get_contents('./people.txt', FILE_USE_INCLUDE_PATH);
?>

示例 #3 读取文件的一部分

<?php
// 从第 21 个字符开始读取 14 个字符
$section = file_get_contents('./people.txt', FALSE, NULL, 20, 14);
var_dump($section);
?>

上面的例子将输出类似于

string(14) "lle Bjori Ro"

示例 #4 使用流上下文

<?php
// 创建一个流
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);

$context = stream_context_create($opts);

// 使用上面设置的HTTP头打开文件
$file = file_get_contents('http://www.example.com/', false, $context);
?>

备注

注意: 此函数是二进制安全的。

提示

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

警告

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

参见

添加注释

用户贡献注释 5 条注释

Bart Friederichs
12年前
file_get_contents 可以执行 POST 请求,首先为此创建一个上下文。

<?php

$opts
= array('http' =>
array(
'method' => 'POST',
'header' => "Content-Type: text/xml\r\n".
"Authorization: Basic ".base64_encode("$https_user:$https_password")."\r\n",
'content' => $body,
'timeout' => 60
)
);

$context = stream_context_create($opts);
$url = 'https://'.$https_server;
$result = file_get_contents($url, false, $context, -1, 40000);

?>
KC
1年前
如果使用负偏移量来获取文件的结尾,并且文件长度小于偏移量,则 file_get_contents() 将返回 false。

如果希望在文件小于负偏移量时只返回可用内容,则可以重试。

例如……

$contents = file_get_contents( $log_file, false, null, -4096 ); // 获取最后 4KB

if ( false === $contents ) {
// 可能出错,或者文件大小小于 4KB。

$contents = file_get_contents( $log_file, false, null );

if ( false === $contents ) {
// 处理真正的错误。
}
}
brentcontact at daha dot us
1年前
为了防止混合内容,大多数浏览器/函数如果只指定 // 而不是 http://https://.,则将使用已使用的协议。file_get_contents 并非如此。必须指定协议。

这不起作用
<?php
$jsonData
= file_get_contents('//example.com/file.json');
print
$jsonData;
?>

不使用双斜杠只指定 'example.com/file.json' 也不起作用。

在 Apache 2.4 上运行时,使用 $_SERVER['REQUEST_SCHEME'] 是更好的协议无关方法。
<?php
$jsonData
= file_get_contents($_SERVER['REQUEST_SCHEME'].'://example.com/file.json');
print
$jsonData;
?>

如果使用其他 Web 服务器,则可能需要以其他方式获取协议或硬编码它。
daniel at dangarbri dot tech
1年前
请注意,如果 HTTP 请求失败但仍然有响应主体,则结果仍然为 false,而不是可能包含有关请求失败原因的更多详细信息的响应主体。
soger
2年前
此页面几乎没有提及,但是如果您的文件是链接,则 $http_response_header 将填充 HTTP 标头。例如,如果您期望一个图像,您可以这样做

<?php
$data
= file_get_contents('https://example.net/some-link');

$mimetype = null;
foreach (
$http_response_header as $v) {
if (
preg_match('/^content\-type:\s*(image\/[^;\s\n\r]+)/i', $v, $m)) {
$mimetype = $m[1];
}
}

if (!
$mimetype) {
// 不是图像
}
To Top