纠正PHP方式来检查外部图像是否存在?

时间:2012-12-19 16:37:16

标签: php image exists

我知道答案中至少有10个相同的问题但是它们似乎都没有完美地为我工作。我正在尝试检查内部或外部图像是否存在(图像URL是否有效?)。

  1. fopen($url, 'r')失败,除非我使用@fopen()

    Warning: fopen(http://example.com/img.jpg) [function.fopen]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in file.php on line 21
    
  2. 当图像不存在时,
  3. getimagesize($img)失败(PHP 5.3.8):

    Warning: getimagesize() [function.getimagesize]: php_network_getaddresses: getaddrinfo failed
    
  4. CURL失败,因为某些服务器不支持它(尽管它主要出现在各处)。
  5. fileExists()失败,因为它无法与外部网址一起使用 无法检查我们是否正在处理图片。
  6. 这种问题最常见的四种方法都是错误的。这样做的正确方法是什么?

9 个答案:

答案 0 :(得分:15)

getimagesize($img) fails when image doesn't exist:我不确定你明白自己想要什么......

来自PHP DOC

  

getimagesize()函数将确定任何给定图像文件的大小,并返回尺寸以及文件类型和要在普通HTML IMG标记内使用的高度/宽度文本字符串以及相应的HTTP内容类型。 / p>      

失败时,返回FALSE。

实施例

$img = array("http://i.stack.imgur.com/52Ha1.png","http://example.com/img.jpg");
foreach ( $img as $v ) {
    echo $v, getimagesize($v) ? " = OK  \n" : " = Not valid \n";
}

输出

http://i.stack.imgur.com/52Ha1.png = OK  
http://example.com/img.jpg = Not valid 

getimagesize效果很好

编辑

  

@Paul。但你的问题基本上是说“我如何处理这个,所以当出现错误时我不会收到错误”。答案就是“你做不到”。因为所有这些函数都会在出现错误时触发错误。所以(如果你不想要错误)你会压制它。这一点在生产中都不重要,因为你不应该显示错误;-) - DaveRandom

答案 1 :(得分:13)

此代码实际上是检查文件...但是,它确实适用于图像!

$url = "http://www.myfico.com/Images/sample_overlay.gif";
$header_response = get_headers($url, 1);
if ( strpos( $header_response[0], "404" ) !== false )
{
   // FILE DOES NOT EXIST
} 
else 
{
   // FILE EXISTS!!
}

答案 2 :(得分:4)

function checkExternalFile($url)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $retCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return $retCode;
}

$fileExists = checkExternalFile("http://example.com/your/url/here.jpg");

// $fileExists > 400 = not found
// $fileExists = 200 = found.

答案 3 :(得分:1)

如果您使用的是PHP> = 5.0.0,则可以将其他参数传递给fopen以指定HTTP的上下文选项,其中包括是否忽略失败状态代码。

$contextOptions = array( 'http' => array('ignore_errors' => true));

$context = stream_context_create($contextOptions);

$handle = fopen($url, 'r', false, $context);

答案 4 :(得分:0)

您可以使用PEAR / HTTP_Request2包。你可以找到它here

这是一个例子。 Example希望您已正确安装或下载HTTP_Request2软件包。它使用旧式套接字适配器,而不是卷曲。

<?php

require_once 'HTTP/Request2.php';
require_once 'HTTP/Request2/Adapter/Socket.php';

$request = new HTTP_Request2 (
    $your_url, 
    HTTP_Request2::METHOD_GET,
    array('adapter' => new HTTP_Request2_Adapter_Socket())
);

switch($request->send()->getResponseCode()) {

    case 404 : 
        echo 'not found';
        break;

    case 200 :
        echo 'found';
        break;

    default :
        echo 'needs further attention';

}

答案 5 :(得分:0)

使用fsockopen,连接到服务器,发送HEAD请求并查看您获得的状态。

您需要了解问题的唯一时间是域名是否存在。

示例代码:

$file = "http://example.com/img.jpg";
$path = parse_url($file);
$fp = @fsockopen($path['host'],$path['port']?:80);
if( !$fp) echo "Failed to connect... Either server is down or host doesn't exist.";
else {
  fputs($fp,"HEAD ".$file." HTTP/1.0\r\n"
     ."Host: ".$path['host']."\r\n\r\n");
  $firstline = fgets($fp);
  list(,$status,$statustext) = explode(" ",$firstline,3);
  if( $status == 200) echo "OK!";
  else "Status ".$status." ".$statustext."...";
}

答案 6 :(得分:0)

我发现尝试抓住最好的解决方案。它对我很好。

try{
      list($width, $height) = getimagesize($h_image->image_url);
   }
catch (Exception $e)
    {
    }

答案 7 :(得分:0)

我知道你写过“没有卷曲”,但仍然有人会发现这有用:

function curl_head($url) {

    $ch = curl_init($url);

    //curl_setopt($ch, CURLOPT_USERAGENT, 'Your user agent');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1); # get headers
    curl_setopt($ch, CURLOPT_NOBODY, 1); # omit body
    //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); # do SSL check
    //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); # verify domain within cert
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); # follow "Location" redirs
    //curl_setopt($ch, CURLOPT_TIMEOUT_MS, 700); # dies after 700ms

    $result = curl_exec($ch);

    curl_close($ch);

    return $result;
}

print_r(curl_head('https://www.example.com/image.jpg'));

您会在返回的标头数组中看到类似HTTP/1.1 200 OKHTTP/1.1 404 Not Found的内容。您还可以使用curl multi执行多个并行请求。

答案 8 :(得分:-1)

有多个步骤,没有单一解决方案:

  1. 验证网址
  2. 检查文件是否可用(可以直接使用步骤3完成)
  3. 将图像下载到tmp文件中。
  4. 使用getimagesize检查图像的大小。
  5. 对于这种工作,您可以捕获异常并妥善处理它们以定义您的答案。在这种情况下,您甚至可以抑制错误,因为它们意图可能会失败。所以你正确处理错误。

    因为在没有下载实际图像的情况下无法对其进行100%检查。因此,步骤1和2是必需的,3和4是可选的,以获得更明确的答案。