web-dev-qa-db-ja.com

正しいPHP外部イメージが存在するかどうかを確認する方法は?

答えのある同じ質問が少なくとも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. getimagesize($img)は、画像が存在しない場合に失敗します(PHP 5.3.8):

    _Warning: getimagesize() [function.getimagesize]: php_network_getaddresses: getaddrinfo failed
    _
  3. CURLは、一部のサーバーでサポートされていないため失敗します(ただし、ほとんどすべての場所に存在します)。
  4. fileExists()は、外部URLで機能せず、画像を処理しているかどうかを確認できないため、失敗します。

そのような質問に対する最も一般的な答えである4つの方法は間違っています。それを行う正しい方法は何でしょうか?

13
Atadj

このコードは実際にはファイルをチェックするためのものです...しかし、それは画像に対しては機能します!

$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!!
}
14
sk8terboi87 ツ
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.
4
kipzes

PHP> = 5.0.0を使用している場合は、追加のパラメーターをfopenに渡して、HTTPのコンテキストオプションを指定できます。その中には、障害ステータスコードを無視するかどうかが含まれます。

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

$context = stream_context_create($contextOptions);

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

あなたが「カールなし」と書いたことは知っていますが、それでも、誰かがこれが役立つと思うかもしれません。

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 OKまたはHTTP/1.1 404 Not Foundのようなものが表示されます。 curl multiを使用して複数の並列リクエストを実行することもできます。

0
Jasom Dotnet

これには、PEAR/HTTP_Request2パッケージを使用できます。あなたはそれを見つけることができます ここ

ここに例があります。この例では、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';

}
0
hek2mgl

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."...";
}
0

私はこれに対する最良の解決策を見つけてみてください。それは私とうまく働いています。

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