if
fclose
fopen
タイプのものを見つけると、ページの読み込みが非常に遅くなります。
基本的に私がやろうとしていることは次のとおりです。ウェブサイトのリストがあり、それらの横にファビコンを表示したいです。ただし、サイトにサイトがない場合は、壊れた画像を表示するのではなく、別の画像に置き換えたいと思います。
CURLOPT_NOBODY経由でHTTP HEADメソッドを使用するようにcurlに指示できます。
多かれ少なかれ
$ch = curl_init("http://www.example.com/favicon.ico");
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// $retcode >= 400 -> not found, $retcode = 200, found.
curl_close($ch);
とにかく、TCP接続の確立と終了ではなく、HTTP転送のコストのみを節約します。ファビコンが小さいため、あまり改善されないかもしれません。
結果がローカルでキャッシュされるのが遅すぎると判明した場合は、良い考えのようです。 HEADは、ファイルの時刻を確認し、ヘッダーで返します。ブラウザのように、アイコンのCURLINFO_FILETIMEを取得できます。キャッシュにURL => [favicon、timestamp]を保存できます。その後、タイムスタンプを比較して、ファビコンを再読み込みできます。
Piesが言うように、cURLを使用できます。 cURLを取得してヘッダーのみを提供し、本文は提供しないため、より高速になります。リクエストがタイムアウトになるのを待つため、不良ドメインは常に時間がかかる可能性があります。おそらくcURLを使用してタイムアウトの長さを変更できます。
以下に例を示します。
function remoteFileExists($url) {
$curl = curl_init($url);
//don't fetch the actual page, you only want to check the connection is ok
curl_setopt($curl, CURLOPT_NOBODY, true);
//do request
$result = curl_exec($curl);
$ret = false;
//if request did not fail
if ($result !== false) {
//if request was ok, check response code
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode == 200) {
$ret = true;
}
}
curl_close($curl);
return $ret;
}
$exists = remoteFileExists('http://stackoverflow.com/favicon.ico');
if ($exists) {
echo 'file exists';
} else {
echo 'file does not exist';
}
CoolGooseのソリューションは優れていますが、これは大きなファイルの場合は高速です(1バイトしか読み取ろうとしないため)。
if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) {
$image = $default_image;
}
これは元の質問への答えではなく、あなたがやろうとしていることをするためのより良い方法です:
実際にサイトのファビコンを直接取得しようとする代わりに(/favicon.png、/favicon.ico、/favicon.gif、または/path/to/favicon.pngの場合もあります)、googleを使用します。
<img src="http://www.google.com/s2/favicons?domain=[domain]">
できた.
画像を扱う場合は、getimagesizeを使用します。 file_existsとは異なり、この組み込み関数はリモートファイルをサポートします。画像情報(幅、高さ、タイプなど)を含む配列を返します。必要なのは、配列の最初の要素(幅)を確認することだけです。 print_rを使用して配列の内容を出力します
$imageArray = getimagesize("http://www.example.com/image.jpg");
if($imageArray[0])
{
echo "it's an image and here is the image's info<br>";
print_r($imageArray);
}
else
{
echo "invalid image";
}
最も投票された回答の完全な機能:
function remote_file_exists($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if( $httpCode == 200 ){return true;}
}
次のように使用できます。
if(remote_file_exists($url))
{
//file exists, do something
}
これは、HTTPステータスコード(404 = not found)を取得することで実行できます。これは、 file_get_contents
ドキュメント コンテキストオプションを使用します。次のコードはリダイレクトを考慮して、最終宛先のステータスコードを返します( Demo ):
$url = 'http://example.com/';
$code = FALSE;
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1
);
$body = file_get_contents($url, NULL, stream_context_create($options));
foreach($http_response_header as $header)
sscanf($header, 'HTTP/%*d.%*d %d', $code);
echo "Status code: $code";
リダイレクトを追跡したくない場合は、同様に実行できます( Demo ):
$url = 'http://example.com/';
$code = FALSE;
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1,
'max_redirects' => 0
);
$body = file_get_contents($url, NULL, stream_context_create($options));
sscanf($http_response_header[0], 'HTTP/%*d.%*d %d', $code);
echo "Status code: $code";
使用中の関数、オプション、変数のいくつかは、私が書いたブログ投稿で詳細に説明されています: HEAD [最初にPHP Streams 。
allow_url_fopen設定がセキュリティ上の理由でオフに設定されている場合、URLのチェックにPHPの組み込み関数が機能しない場合があります。 Curlの方が良いオプションです後の段階でコードを変更する必要がないためです。以下は、有効なURLを確認するために使用したコードです。
$url = str_replace(' ', '%20', $url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300){ return true; } else { return false; }
CURLOPT_SSL_VERIFYPEERオプションに注意してください。これは、URLがHTTPSで始まることも確認します。
if (false === file_get_contents("http://example.com/path/to/image")) {
$image = $default_image;
}
動作するはずです;)
根本的な解決策は、デフォルトのアイコンの上のdivに、ファビコンを背景画像として表示することです。これにより、破損した画像を表示せずに、すべてのオーバーヘッドがクライアントに置かれます(背景画像の欠落は、すべてのブラウザーで無視されます)。
イメージの存在を確認するには、 exif_imagetype
が getimagesize
よりも優先されるべきです。
E_NOTICE
を抑制するには、エラー制御演算子(@
)を付加するだけです。
if (@exif_imagetype($filename)) {
// Image exist
}
ボーナスとして、IMAGETYPE_XXX
からの戻り値(exif_imagetype
)を使用すると、image_type_to_mime_type
/image_type_to_extension
を使用してMIMEタイプまたはファイル拡張子を取得することもできます。
次を使用できます。
$file = 'http://mysite.co.za/images/favicon.ico';
$file_exists = (@fopen($file, "r")) ? true : false;
画像がURLに存在するかどうかを確認しようとしたときに私のために働いた
function remote_file_exists($url){
return(bool)preg_match('~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url)));
}
$ff = "http://www.emeditor.com/pub/emed32_11.0.5.exe";
if(remote_file_exists($ff)){
echo "file exist!";
}
else{
echo "file not exist!!!";
}
以下を使用できます。
$url=getimagesize(“http://www.flickr.com/photos/27505599@N07/2564389539/”);
if(!is_array($url))
{
$default_image =”…/directoryFolder/junal.jpg”;
}
URIコンテンツはまったく必要ないため、GETではなくHEADリクエストを発行する必要があります。 Piesが上記で述べたように、ステータスコード(200から299の範囲で、オプションで3xxリダイレクトに従うことができます)を確認する必要があります。
回答の質問には、役立つ可能性のある多くのコード例が含まれています。 PHP/Curl:HEAD一部のサイトではリクエストに時間がかかる
これは、PHPにリモートファイルが存在するかどうかを確認するのに役立ちます:
$url = 'https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico';
$header_response = get_headers($url, 1);
if ( strpos( $header_response[0], "404" ) !== false ) {
echo 'File does NOT exist';
} else {
echo 'File exists';
}
ここでget_headers()を使用するすべての回答はGETリクエストを実行しています。 HEADリクエストを行う方がはるかに高速/安価です。
Get_headers()がGETの代わりにHEADリクエストを行うようにするには、これを追加する必要があります。
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
ファイルが存在するかどうかを確認するには、コードは次のようになります。
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
$headers = get_headers('http://website.com/dir/file.jpg', 1);
$file_found = stristr($headers[0], '200');
$ file_foundは、明らかにfalseまたはtrueを返します。
さらに洗練された代替手段があります。 JQueryトリックを使用して、すべてのクライアント側のチェックを行うことができます。
$('a[href^="http://"]').filter(function(){
return this.hostname && this.hostname !== location.hostname;
}).each(function() {
var link = jQuery(this);
var faviconURL =
link.attr('href').replace(/^(http:\/\/[^\/]+).*$/, '$1')+'/favicon.ico';
var faviconIMG = jQuery('<img src="favicon.png" alt="" />')['appendTo'](link);
var extImg = new Image();
extImg.src = faviconURL;
if (extImg.complete)
faviconIMG.attr('src', faviconURL);
else
extImg.onload = function() { faviconIMG.attr('src', faviconURL); };
});
http://snipplr.com/view/18782/add-a-favicon-near-external-links-with-jquery/ (元のブログは現在ダウンしています)
ファイルが外部でホストされていない場合、リモートURLをWebサーバー上の絶対パスに変換できます。そうすれば、CURLやfile_get_contentsなどを呼び出す必要はありません。
function remoteFileExists($url) {
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
$urlParts = parse_url( $url );
if ( !isset( $urlParts['path'] ) )
return false;
if ( is_file( $root . $urlParts['path'] ) )
return true;
else
return false;
}
remoteFileExists( 'https://www.yourdomain.com/path/to/remote/image.png' );
注:この関数を使用するには、ウェブサーバーにDOCUMENT_ROOTを設定する必要があります
ファイルがリモートに存在しない場合、これがもっと速いかどうかはわかりません is_file() ですが、試してみてください。
$favIcon = 'default FavIcon';
if(is_file($remotePath)) {
$favIcon = file_get_contents($remotePath);
}