46

我使用以下 PHP 函数:

file_get_contents('http://example.com');

每当我在某个服务器上执行此操作时,结果都是空的。当我在其他任何地方这样做时,结果就是页面的内容可能是什么。但是,当我在结果为空的服务器上,在本地使用该函数时 - 无需访问外部 URL ( file_get_contents('../simple/internal/path.html');),它确实有效。

现在,我很确定它与某个 php.ini 配置有关。然而,我不确定是一个。请帮忙。

4

8 回答 8

44

您正在寻找的设置是allow_url_fopen.

您有两种方法可以在不更改 php.ini 的情况下绕过它,其中一种是使用fsockopen(),另一种是使用cURL

我建议无论如何都使用 cURL file_get_contents(),因为它是为此而构建的。

于 2010-08-15T17:24:51.637 回答
43

作为 Aillyn 的回答的补充,您可以使用如下函数来模仿 file_get_contents 的行为:

function get_content($URL){
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_URL, $URL);
      $data = curl_exec($ch);
      curl_close($ch);
      return $data;
}

echo get_content('http://example.com');
于 2010-08-15T18:26:07.543 回答
4

与ini配置设置有关allow_url_fopen

您应该知道,启用该选项可能会使您的代码中的一些错误可被利用。

例如,这种无法验证输入的失败可能会变成一个成熟的远程代码执行漏洞:

copy($_GET["file"], "."); 
于 2010-08-15T17:24:52.133 回答
4
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.your_external_website.com");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);

最适合 http url,但是如何打开 https url 帮助我

于 2013-02-28T09:55:14.453 回答
3

上面提供的答案解决了问题,但没有解释 OP 描述的奇怪行为。这种解释应该有助于任何人在开发环境中测试站点之间的通信,其中这些站点都驻留在同一主机上(和同一虚拟主机;我正在使用 apache 2.4 和 php7.0)。

我遇到的一个微妙之处file_get_contents()在这里绝对相关但未解决(可能是因为它几乎没有记录或没有记录在我可以告诉的内容中,或者记录在我找不到的晦涩的 php 安全模型白皮书中)。

在所有相关上下文(例如,等)中allow_url_fopen设置为并在命令行上下文(即)中设置为,将允许调用本地资源并且不会记录警告,例如:Off/etc/php/7.0/apache2/php.ini/etc/php/7.0/fpm/php.iniallow_url_fopenOn/etc/php/7.0/cli/php.inifile_get_contents()

file_get_contents('php://input');

或者

// Path outside document root that webserver user agent has permission to read. e.g. for an apache2 webserver this user agent might be www-data so a file at /etc/php/7.0/filetoaccess would be successfully read if www-data had permission to read this file
file_get_contents('<file path to file on local machine user agent can access>');

或者

// Relative path in same document root
file_get_contents('data/filename.dat')

总而言之,该限制allow_url_fopen = Off类似于链中iptables的一条规则OUTPUT,其中该限制仅在尝试“退出系统”或“更改上下文”时应用。

NB在命令行上下文中allow_url_fopen设置为On(即/etc/php/7.0/cli/php.ini)是我在系统上的设置,但我怀疑它与我提供的解释无关,即使它设置为,Off除非您当然是通过从命令行本身。我没有在命令行上下文中使用allow_url_fopenset to测试行为。Off

于 2017-06-05T17:02:06.140 回答
1

这也将为外部链接提供绝对路径,而无需使用 php.ini

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.your_external_website.com");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
$result = preg_replace("#(<\s*a\s+[^>]*href\s*=\s*[\"'])(?!http)([^\"'>]+)([\"'>]+)#",'$1http://www.your_external_website.com/$2$3', $result);
echo $result
?>
于 2012-07-25T12:50:26.517 回答
1

在 PHP INI 部分中从 cPanel 或 WHM 启用 allow_url_fopen

于 2021-02-01T19:09:20.673 回答
0

添加:

allow_url_fopen=1

在你的php.ini文件中。如果您使用的是共享主机,请先创建一个。

于 2012-03-31T08:10:17.040 回答