Лучшее, что я смог найти, if
fclose
fopen
шрифт, заставляет страницу загружаться очень медленно.
В основном я пытаюсь сделать следующее: у меня есть список веб-сайтов, и я хочу отображать их значки рядом с ними. Однако, если на сайте его нет, я бы хотел заменить его другим изображением, а не отображать неработающее изображение.
onerror
изображение, например, решение с использованием jQueryОтветы:
Вы можете указать curl использовать метод HTTP HEAD через CURLOPT_NOBODY.
Более менее
$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);
В любом случае, вы экономите только на HTTP-передаче, но не на установлении и закрытии TCP-соединения. А поскольку фавиконы маленькие, особых улучшений вы не увидите.
Кэширование результата локально кажется хорошей идеей, если он оказывается слишком медленным. HEAD проверяет время файла и возвращает его в заголовках. Вы можете делать как браузеры и получать CURLINFO_FILETIME значка. В вашем кеше вы можете сохранить URL => [значок, временная метка]. Затем вы можете сравнить отметку времени и перезагрузить значок.
источник
retcode
ошибки во всех 400 кодах, поэтому проверка будет>=
не простой>
Как говорят пироги, вы можете использовать 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; }
источник
fopen
- если код возврата запроса 404, fopen вернет false.Это не ответ на ваш исходный вопрос, а лучший способ сделать то, что вы пытаетесь сделать:
Вместо того, чтобы пытаться напрямую получить значок сайта (что очень неудобно, учитывая, что это может быть /favicon.png, /favicon.ico, /favicon.gif или даже /path/to/favicon.png), используйте google:
<img src="http://www.google.com/s2/favicons?domain=[domain]">
Выполнено.
источник
Полная функция ответа, получившего наибольшее количество голосов:
function remote_file_exists($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); # handles 301/2 redirects 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 }
источник
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
. Я обновил ответ, чтобы обрабатывать302
перенаправления.Если вы имеете дело с изображениями, используйте 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"; }
источник
@
передgetimagesize
, но чувствуя себя виноватым за этот взлом.exif_imagetype
, и это намного быстрее stackoverflow.com/a/38295345/1250044Это можно сделать, получив код состояния HTTP (404 = не найден), что возможно с помощью
file_get_contents
Документов, использующих параметры контекста. Следующий код учитывает перенаправления и возвращает код состояния конечного пункта назначения ( Демо ):$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";
Если вы не хотите следовать перенаправлениям, вы можете сделать это аналогично ( Демо ):
$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 first with PHP Streams .
источник
$http_response_header
см. Php.net/manual/en/reserved.variables.httpresponseheader.php .if (false === file_get_contents("http://example.com/path/to/image")) { $image = $default_image; }
Должно сработать ;)
источник
Встроенные функции PHP могут не работать для проверки URL, если параметр allow_url_fopen отключен по соображениям безопасности. 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.
источник
exif_imagetype
Следует предпочесть проверку наличия изображенийgetimagesize
, так как это намного быстрее.Чтобы подавить
E_NOTICE
, просто добавьте оператор контроля ошибок (@
).if (@exif_imagetype($filename)) { // Image exist }
В качестве бонуса с возвращаемым значением (
IMAGETYPE_XXX
)exif_imagetype
мы также можем получить тип mime или расширение файла сimage_type_to_mime_type
/image_type_to_extension
.источник
Радикальным решением было бы отображать значки как фоновые изображения в блоке div над значком по умолчанию. Таким образом, все накладные расходы будут возложены на клиента, но при этом не будут отображаться битые изображения (отсутствующие фоновые изображения игнорируются во всех браузерах AFAIK).
источник
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!!!"; }
источник
Вы можете использовать следующее:
$file = 'http://mysite.co.za/images/favicon.ico'; $file_exists = (@fopen($file, "r")) ? true : false;
Работал для меня при попытке проверить, существует ли изображение по URL-адресу
источник
Ты можешь использовать :
$url=getimagesize(“http://www.flickr.com/photos/27505599@N07/2564389539/”); if(!is_array($url)) { $default_image =”…/directoryFolder/junal.jpg”; }
источник
Это работает для меня, чтобы проверить, существует ли удаленный файл в 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'; }
источник
Вы должны отправлять запросы HEAD, а не GET, потому что вам вообще не нужно содержимое URI. Как сказано выше, вы должны проверить код состояния (в диапазонах 200–299, при желании вы можете следовать перенаправлениям 3xx).
Вопрос с ответами содержит много примеров кода, которые могут быть полезны: PHP / Curl: HEAD Request занимает много времени на некоторых сайтах
источник
Есть еще более изощренная альтернатива. Вы можете проверить все на стороне клиента, используя трюк 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/ (исходный блог в настоящее время недоступен)
источник
все ответы здесь, которые используют get_headers (), выполняют запрос GET. Гораздо быстрее / дешевле просто выполнить запрос HEAD.
Чтобы убедиться, что get_headers () выполняет запрос HEAD вместо GET, вы должны добавить это:
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.
источник
Не знаю, работает ли это быстрее, когда файл не существует удаленно, is_file () , но вы можете попробовать .
$favIcon = 'default FavIcon'; if(is_file($remotePath)) { $favIcon = file_get_contents($remotePath); }
источник
var_dump(is_file('http://cdn.sstatic.net/stackoverflow/img/sprites.png')); bool(false)
Если файл не размещен на внешнем сервере, вы можете преобразовать удаленный URL-адрес в абсолютный путь на своем веб-сервере. Таким образом, вам не нужно вызывать 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' );
источник
Если вы используете фреймворк Symfony, есть также более простой способ
HttpClientInterface
:private function remoteFileExists(string $url, HttpClientInterface $client): bool { $response = $client->request( 'GET', $url //e.g. http://example.com/file.txt ); return $response->getStatusCode() == 200; }
Документация для HttpClient также очень хороша и, возможно, стоит изучить, если вам нужен более конкретный подход: https://symfony.com/doc/current/http_client.html
источник
Вы можете использовать файловую систему: используйте Symfony \ Component \ Filesystem \ Filesystem; используйте Symfony \ Component \ Filesystem \ Exception \ IOExceptionInterface;
и отметьте $ fileSystem = new Filesystem (); if ($ fileSystem-> exists ('path_to_file') == true) {...
источник