php_network_getaddresses: getaddrinfo 失败: 名称或服务未知

75

这是我的代码片段:

$fp = fsockopen($s['url'], 80, $errno, $errstr, 5);
if($fp){
        fwrite($fp, $out);
        fclose($fp);

运行代码后,输出:

无法连接到www.mydomain.net/1/file.php:80 (php_network_getaddresses: getaddrinfo失败:名称或服务未知)

我使用这个来提交GET数据到$s['url']

我不知道为什么。希望能得到帮助。


远程地址可达吗?DNS解析了吗? - farzad
1
是的。事实上,我目前让它访问同一服务器上的一个URL。 - Rob
2
我遇到了相同的错误,但我认为这是由于“etc/resolf.conf”和“etc/hosts”中的错误服务器配置引起的。 - molokoloco
答案是更正你的/etc/hosts文件。确保URL指向正确的位置(通常是localhost)。 - tread
我在使用“new mysqli”时遇到了这个问题,其中数据库主机名不在/etc/hosts/中。 - zzapper
1
我的错误非常愚蠢...... localhost 的拼写错了 :) - Ghanshyam Bagul
11个回答

38

使用fsockopen无法直接连接到远程主机上的路径。URL www.mydomain.net/1/file.php 包含了路径,而该函数的第一个参数只能是主机名 www.mydomain.net

如果您想访问远程URL,那么最好使用file_get_contents()。您可以向该函数提供完整的URL,并使用正常的HTTP请求获取该位置的内容。

如果您只想发送HTTP请求并忽略响应,则可以使用fsockopen()并手动发送HTTP请求头,忽略任何响应。不过,使用cURL或仅使用旧式的fopen()可能更容易,后者将打开连接但不一定读取任何响应。如果您想使用fsockopen()来完成,则可能如下所示:

$fp = fsockopen("www.mydomain.net", 80, $errno, $errstr, 30);
fputs($fp, "GET /1/file.php HTTP/1.1\n");
fputs($fp, "Host: www.mydomain.net\n");
fputs($fp, "Connection: close\n\n"); 

当然,这也意味着错误处理要由您自己完成,但它会避免您浪费时间去读取响应。


我不需要检索内容,只需提交GET数据。这会有什么特别的影响吗?还是说无论如何都可以? 即 file_get_contents("http://www.domain.com/file.php?action=this&get=that"); - Rob
1
没关系,你可以忽略file_get_contents的返回值。 - elias
想到了。我会尝试一下,然后回来。 - Rob
2
@Rob - elias是正确的,你可以忽略返回值。如果你担心进行完整的HTTP请求会有开销(除非该URL返回大量信息),我更新了我的答案,提供了一个粗糙的fsockopen()方法手动发送HTTP请求头。 - zombat

29

我在本地测试服务器和本地测试域名(例如:www.testdomain.loc)上遇到了类似的问题,使用函数GetImageSize()

通过在本地服务器的hosts文件中添加主机名解决了这个问题:

在文件/etc/hosts中添加:

192.168.1.1 www.testdomain.loc

虽然这对大多数基于DNS解析的方法有效,但它不适用于fsockopen(),因此无法验证此问题(为了验证,请创建一个测试文件,将其复制并粘贴到OP代码中,并使用类似于www.mydomain.net/1/file.php的Web URL,您就会明白为什么)。 - newfurniturey

24

如果您只想向URL提交GET数据,那么您应该使用像file_get_contents()这样简单直接的东西。

$myGetData = "?var1=val1&var2=val2";
file_get_contents($url.$myGetData);

好吧,这让事情变得太容易了。等一下,我试一试。 - Rob
3
欢迎来到PHP的简单世界xD。 - elias
7
这是一个替代方案,可解决代码问题,但不能解决基础设施问题(DNS查找失败)。由于我在Drupal内也遇到了相同的问题,因此修改别人贡献的项目并不是我想要的选项:相反,我可以推荐这个主题中的另一个答案,涉及/etc/hosts,它确实修复了我的DNS问题。 - J-P
1
我刚遇到了同样的问题,在运行Wireshark后,我发现路由器还没有更新它的DNS缓存,并且新创建的子域名还没有被解析。 - Simon A. Eugster

10

我遇到了类似的问题(与 https://github.com/PHPMailer/PHPMailer 相关),只需重新加载 PHP ,一切就开始正常工作了。

对于 Centos 6 和 7:

service php-fpm restart 

+1 你真是救星,我升级了 PHP 版本,一直在想为什么会出现错误,重启 Apache 解决了问题。谢谢! - Alyas
真是太烦人了。我尝试了很多方法来解决问题,然后看到了你的消息。谢谢,它帮了我很大的忙。 - Mate Paiva

4
$url = "http://user:pass@www.example.com/abc.php?var1=def";
$contents = file_get_contents($url);
echo $contents;

3
我遇到了相同的fsocket()错误,我只是更新了hosts文件
  1. 通过SSH登录到CentOS服务器。输入用户名和密码
  2. cd /etc/
  3. ls                                     //"只是查看文件列表"
  4. vi hosts                                   //"编辑主机文件"
  5. i                                    //"输入i以进入插入模式"
  6. 95.183.24.10                 [mail_server_name] in my case ("mail.kingologic.com")
  7. 按ESC键
  8. 输入ZZ
希望这可以解决您的问题。
如果有任何进一步的问题,请在http://kingologic.com上联系我。

2
您正在尝试打开到远程主机上文件的套接字,但是不正确。您可以建立一个套接字连接(TCP/UDP)到远程主机上的端口号。因此,您的代码应该像这样:
fsockopen('www.mysite.com', 80);

如果你想创建一个指向远程文件的文件指针资源,可以使用fopen()函数。但是,为了做到这一点,你需要同时指定应用程序协议。
PHP为URL文件打开提供了默认的流包装器。根据URL的模式,适当的流包装器将在内部被调用。你尝试打开的URL没有有效的方案来解决这个问题。确保它有像"http://"或"ftp://"这样的方案。
所以代码应该像这样:
$fp = fopen('http://www.mysite.com/path/file.txt');

此外,我认为HTTP流包装器(处理具有http模式的URL上的文件资源操作)不支持写入数据。您可以使用fread()通过HTTP读取URL的内容,但我不确定是否支持写入。
编辑: 从评论和其他答案中,我发现您想要向指定的URL发送HTTP请求。本答案中描述的方法是用于从远程URL接收数据。如果您想发送数据,可以使用http_request()来完成此操作。

我正在做的是向 $s['url'] 提交 GET 数据。 - Rob
可以用从GET获得的数据替换URL中硬编码的地址,但要确保有一个模式,如果没有,请添加默认的'http://'。使用parse_url()函数来确保URL中有一个模式。 - farzad

1
在我的情况下,这个错误是由于debian上/etc/nsswitch.conf配置不正确造成的。
我已经替换了字符串。
hosts:          files myhostname mdns4_minimal [NOTFOUND=return] dns

使用

hosts:          files dns

现在一切都正常运行。

我认为 /etc/nsswitch.conf 文件中的第一行不应该有问题。在我的 Debian 9 安装中,以及 Debian 8 中都是这样的,网络连接也很正常。然而,在从 Debian 8 升级到 9 后立即出现了这些错误。事实证明,这只是一个简单的重启 web 服务器的问题 - 在我的情况下是 Apache。 - David

0

尝试设置ENV PATH。将PHP路径添加到ENV PATH中。

为了使此扩展程序正常工作,必须将DLL文件添加到Windows系统PATH中。有关如何执行此操作的信息,请参阅名为“如何在Windows上将我的PHP目录添加到PATH”的FAQ。虽然将DLL文件从PHP文件夹复制到Windows系统目录也可以(因为系统目录默认在系统的PATH中),但不建议这样做。此扩展程序需要以下文件位于PATH中:libeay32.dll

http://php.net/manual/en/openssl.installation.php


0

简单来说,您的网站被阻止访问网络。可能是因为您自动化了某些脚本,导致整个网站被阻止。解决此问题的更好方法是联系该网站并告知您的问题。如果问题是真实存在的,他们可能会考虑解除封锁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接