file_exists或getimagesize仅适用于本地绝对文件路径,而不适用于PHP中的url


file_exists or getimagesize only work with local, absolute file paths, but not with URLs in PHP

我最近更新了我的一个服务器,从那时起,我有一些特定的PHP命令的问题(见下文)。我相信这是一个配置问题,但我已经调查了一些事情,不知道任何进一步。也许你们中有人有好主意:

我使用以下代码来显示内部网站点上的标准徽标或用户定义的徽标:

if(L_HEADER) {
  $logo = L_HEADER;
}
else {
  $logo = 'logo.png';
}
$properties = getimagesize(CONFIG_URL . 'images/' . $logo)

L_HEADER和CONFIG_URL是具有预定义值的常量(另一个文件):

  1. L_HEADER包含"opb_beta.png"
  2. CONFIG_URL包含"http://billing.intranet.opb/"

连接工作正常,这也由Apache日志文件的错误消息确认:

PHP警告:getimagesize(http://billing.intranet.opb/images/opb_beta.png):打开流失败:HTTP请求失败!HTTP/1.1 404未找到
在/var/www/billing/templates/header.inc.php第42行

所以第一个明显的结论是:路径是错误的。但事实并非如此,相信我。我查了差不多一千遍。实际上,第一个奇怪的地方是,在同一文件的代码

的后面几行中,图像被正确地显示和引用:
echo '<img src="' . CONFIG_URL . 'images/' . $logo . '"  
  width="' . $properties[0] . '" height = "' . $properties[1] . '" />";

当我得到上面提到的错误时,高度和宽度是"0",但是查看源代码,URL是好的,手动访问它打开图像,当用手动值替换宽度和高度时,图像显示得很好。

更奇怪的是(也是我当前的finx),当将getimagesize更改为以下内容时,它工作得很好:
$properties = getimagesize($_SERVER['DOCUMENT_ROOT'] . /public_html/images/' . $logo);

我应该提到我正在使用Apache的重定向;这就是为什么在URL中你看不到"public_html",而在第二个例子的绝对路径中你可以看到它。

"file_exists"也是如此。URL不能工作,同一文件的绝对本地路径可以。

另一个好奇:在另一段代码中,我正在检查在线更新。在这里,我使用了一个带有file_exists和fopen的"真实的"公共URL。它看起来像这样,工作得很好:

if(file_exists('http://desk.co.cr/df_stable.txt') {
  if(($handle = fopen('http://desk.co.cr/df_stable.txt', 'r')) !== FALSE) {
    // some other code
  }
}

现在,我已经检查过的东西:

  • 正确设置整个路径的文件权限,其中www-data为所有文件的组和所有者,并对图像文件具有读写权限
  • allow_url_fopen in设置为"On"
  • open_basedir设置为"no value",并且在Apache的虚拟主机定义中没有覆盖。
  • 文件确定存在且语法和路径正确。

一些背景信息:

  • 服务器在Ubuntu 14.04 LTS上运行
  • Apache 2.4.7
  • PHP 5.5.9

现在,我没有主意了

在你的问题中隐藏着你已经发现的重要线索:

另一个好奇:在另一段代码中,我正在检查在线更新。这里,我使用了一个"真实的"公共URL

因此,失败的URL指向非公共域,您的PC已配置为查找正确的IP地址。这很可能是通过运行本地DNS服务器或配置PC的"hosts"文件来硬编码该域的地址来完成的。

当你从服务器本身请求URL时,然而,一个完全不同的DNS配置在起作用,所以可能它根本不知道服务器在哪里-即使它自己!您需要配置服务器的DNS设置或/etc/hosts以匹配您PC上的内容。

一个相关的可能性是服务器配置了相同的地址查找,但是路由器不允许它以这种方式连接到自己。解决这个问题的一种方法是将hosts文件条目指向127.0.0.1,并配置Apache来匹配。

如果您可以在服务器上获得命令行,您可以尝试:

nslookup billing.intranet.opb
# if that returns the right IP address, see if it's reachable:
ping billing.intranet.opb
# and if it's the right server, it will be listening on port 80:
telnet billing.intranet.opb 80
# telnet will either time out, or connect and give you a prompt

如果telnet连接,您甚至可以手动编写HTTP请求(空白行完成请求;不要键入太长时间,否则服务器会跳出来),例如:

HTTP/1.1 HEAD /
Host: billing.intranet.opb