Предположим, у вас есть сценарий генератора эскизов, который принимает исходные изображения в виде URL-адреса. Есть ли способ определить, является ли исходный URL «сломанным» – не существует или ведет к файлу без изображения?
Просто грубая сила, использующая getimagesize()
или другую функцию PHP GD, не является решением, поскольку поддельные измененные URL-адреса, которые могут не быть изображениями вообще ( http://example.com/malicious.exe
или тот же файл, но переименованы как http://example.com/malicious.jpg
) – такие случаи могут быть легко обнаружены PHP перед вызовом GD. Я ищу GD pre-sanitizing, прежде чем GD попробует его батальон при разборе файла.
в качестве первого шага следующее регулярное выражение проверяет, является ли URL-адрес расширением изображения: preg_match('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)([^\s]+(\.(?i)(jpg|png|gif|bmp))$)@', $txt,$url);
используйте функцию file_exists
в php, вы можете проверить URL-адреса с ним.
См. Документацию ниже, показывает, как проверить img … точно, что вам нужно
FILE EXISTS – http://www.php.net/manual/en/function.file-exists.php#93572
URL EXISTS – http://www.php.net/manual/en/function.file-exists.php#85246
Вот альтернативный код для проверки URL. Если вы проверите в браузере, замените \n
на <br/>
<?php $urls = array('http://img.ruphp.com/php/ps_logo2.png', 'http://www.google.com/images/logos/ps_logo2_not_exists.png'); foreach($urls as $url){ echo "$url - "; echo url_exists($url) ? "Exists" : 'Not Exists'; echo "\n\n"; } function url_exists($url) { $hdrs = @get_headers($url); echo @$hdrs[1]."\n"; return is_array($hdrs) ? preg_match('/^HTTP\\/\\d+\\.\\d+\\s+2\\d\\d\\s+.*$/',$hdrs[0]) : false; } ?>
Вывод выглядит следующим образом
http://img.ruphp.com/php/ps_logo2.png - Content-Type: image/png Exists http://www.google.com/images/logos/ps_logo2_not_exists.png - Content-Type: text/html; charset=UTF-8 Not Exists
Я использовал следующее для обнаружения атрибутов для удаленных изображений
$src='http://example.com/image.jpg'; list($width, $height, $type, $attr) = @getimagesize($src);
пример (проверка содержимого stackoverflows «Карьера 2.0»)
$src='http://sstatic.net/ads/img/careers2-ad-header-so.png'; list($width, $height, $type, $attr) = @getimagesize($src); echo '<pre>'; echo $width.'<br>'; echo $height.'<br>'; echo $type.'<br>'; echo $attr.'<br>'; echo '</pre>';
Если $ height, $ width и т. Д. Является нулевым, изображение очевидно не изображение или файл не существует. Использование cURL является чрезмерным и медленным (даже с CURLOPT_HEADER)
Единственный действительно надежный способ – запросить изображение с помощью file_get_contents()
и узнать его тип изображения, используя getimagesize()
.
Только если getimagesize()
возвращает допустимый тип файла, можете ли вы полагаться на то, что это действительно допустимое изображение.
Однако это довольно ресурсоемкий.
Вы можете вообще не делать каких-либо проверок на стороне сервера и добавлять на onerror
событие onerror
JavaScript:
<img src="..." onerror="this.style.display = 'none'">
try for local files <?php if(file_exists($filename)) { //do what you want } else { //give error that file does not exists } ?>
для внешних доменов
$headers = @get_headers($url); if (preg_match("|200|", $headers[0])) { // file exists } else { // file doesn't exist }
Также вы можете использовать запрос curl для этого же.
Быстрое решение для сломанной или не найденной ссылки изображения
я предлагаю вам, чтобы не использовать getimagesize (), потому что он будет первым загружать изображение, тогда он будет проверять размер изображения +, если это не будет изображение, тогда он будет генерировать исключение, поэтому используйте ниже код
if(checkRemoteFile($imgurl)) { //found url, its mean echo "this is image"; } function checkRemoteFile($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); // don't download content curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if(curl_exec($ch)!==FALSE) { return true; } else { return false; } }
Примечание: этот текущий код поможет вам идентифицировать сломанное или не найденное изображение URL-адреса, это не поможет вам определить тип изображения или заголовки
Вы можете проверить код HTTP-кода (он должен быть 200) и заголовок Content-type (изображение / png и т. Д.) Ответа HTTP до того, как вы поместите фактическое изображение через генератор.
Если эти две предпосылки в порядке, после извлечения изображения вы можете вызвать getimagesize()
на нем и посмотреть, разрывается ли он, какой тип MIME он возвращает и т. Д.
вы попробовали метод file_get_contents ()?