13

答えのある同じ質問が少なくとも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 つの方法は間違っています。それを行う正しい方法は何ですか?

4

9 に答える 9

15

getimagesize($img) fails when image doesn't exist:あなたが何を望んでいるのか理解できません.....

PHPドキュメントから

getimagesize() 関数は、指定された画像ファイルのサイズを決定し、通常の HTML IMG タグおよび対応する HTTP コンテンツ タイプ内で使用されるファイル タイプおよび高さ/幅のテキスト文字列と共に寸法を返します。

失敗すると、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

于 2012-12-19T16:47:47.867 に答える
14

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

$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!!
}
于 2012-12-19T16:48:29.023 に答える
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.
于 2013-08-23T08:52:22.303 に答える
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);
于 2012-12-19T16:45:11.727 に答える
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."...";
}
于 2012-12-19T16:43:20.227 に答える
0

これに最適な解決策を試してください。それは私とうまくいっています。

try{
      list($width, $height) = getimagesize($h_image->image_url);
   }
catch (Exception $e)
    {
    }
于 2015-12-31T11:33:08.157 に答える
0

これには 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';

}
于 2012-12-19T16:41:38.467 に答える
-1

複数のステップがあり、単一の解決策はありません。

  1. URLを検証する
  2. ファイルが使用可能かどうかを確認します(手順3で直接実行できます)
  3. イメージをtmpファイルにダウンロードします。
  4. getimagesizeを使用して、画像のサイズを確認します。

この種の作業では、例外をキャッチし、それらを適切に処理して答えを定義できます。この場合、トリックが失敗する可能性があるため、エラーを抑制することもできます。したがって、エラーを正しく処理します。

実際の画像をダウンロードせずに100%チェックすることはできないからです。したがって、ステップ1と2は必須であり、より明確な答えを得るには3と4はオプションです。

于 2012-12-19T16:43:29.593 に答える