내가 찾을 수있는 최선의 if
fclose
fopen
유형은 페이지로드를 정말 느리게 만듭니다.
기본적으로 내가하려는 것은 다음과 같습니다. 웹 사이트 목록이 있고 그 옆에 파비콘을 표시하고 싶습니다. 그러나 사이트에없는 경우 깨진 이미지를 표시하는 대신 다른 이미지로 교체하고 싶습니다.
내가 찾을 수있는 최선의 if
fclose
fopen
유형은 페이지로드를 정말 느리게 만듭니다.
기본적으로 내가하려는 것은 다음과 같습니다. 웹 사이트 목록이 있고 그 옆에 파비콘을 표시하고 싶습니다. 그러나 사이트에없는 경우 깨진 이미지를 표시하는 대신 다른 이미지로 교체하고 싶습니다.
onerror
이미지는 예 jQuery를 이용한 용액
답변:
curl에 CURLOPT_NOBODY를 통해 HTTP HEAD 메소드를 사용하도록 지시 할 수 있습니다.
다소간
$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]를 저장할 수 있습니다. 그런 다음 타임 스탬프를 비교하고 파비콘을 다시로드 할 수 있습니다.
retcode
모든 400 개 코드에 오류가 검증 될 수 있도록 >=
단지>
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;
}
fopen
-요청 반환 코드가 404이면 fopen은 false를 반환합니다.
이것은 원래 질문에 대한 답이 아니지만 수행하려는 작업을 수행하는 더 나은 방법입니다.
실제로 사이트의 favicon을 직접 가져 오려고하는 대신 (/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";
}
exif_imagetype
훨씬 더 빠릅니다. stackoverflow.com/a/38295345/1250044
이는 file_get_contents
문서 에서 컨텍스트 옵션을 사용하여 가능한 HTTP 상태 코드 (404 = 찾을 수 없음)를 가져 와서 수행 할 수 있습니다. 다음 코드는 리디렉션을 고려하고 최종 대상 ( 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";
리디렉션을 따르지 않으려면 다음과 같이 할 수 있습니다 ( 데모 ).
$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를 참조하십시오 .
보안상의 이유로 allow_url_fopen 설정이 off로 설정된 경우 PHP의 내장 기능이 URL 확인에 작동하지 않을 수 있습니다 . 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; }
URL이 HTTPS로 시작하는지도 확인 하는 CURLOPT_SSL_VERIFYPEER 옵션을 참고 하십시오 .
이미지의 존재를 확인하려면을 (를 ) 훨씬 더 빠르기 때문에보다 exif_imagetype
선호해야합니다 getimagesize
.
을 표시하지 않으려면 E_NOTICE
오류 제어 연산자 ( @
)를 앞에 추가하십시오 .
if (@exif_imagetype($filename)) {
// Image exist
}
보너스로 반환 된 값 ( IMAGETYPE_XXX
)을 사용 exif_imagetype
하여 image_type_to_mime_type
/를 사용 하여 MIME 유형 또는 파일 확장자를 가져올 수도 있습니다 image_type_to_extension
.
다음을 사용할 수 있습니다.
$file = 'http://mysite.co.za/images/favicon.ico';
$file_exists = (@fopen($file, "r")) ? true : false;
URL에 이미지가 있는지 확인하려고 할 때 나를 위해 일했습니다.
이것은 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';
}
URI 내용이 전혀 필요하지 않기 때문에 GET 요청이 아닌 HEAD 요청을 발행해야합니다. Pies가 위에서 말했듯이 상태 코드를 확인해야합니다 (200-299 범위에서 선택적으로 3xx 리디렉션을 따를 수 있음).
답변 질문에는 도움이 될 수있는 많은 코드 예제가 포함되어 있습니다. PHP / Curl : 일부 사이트에서 HEAD 요청이 오래 걸립니다.
훨씬 더 정교한 대안이 있습니다. 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 ()가 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는 분명히 거짓 또는 참을 반환합니다.
파일이 원격으로 존재하지 않을 때 이것이 더 빠른지 모르겠지만, 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' );
참고 :이 기능을 사용하려면 웹 서버가 DOCUMENT_ROOT를 채워야합니다.
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
파일 시스템을 사용할 수 있습니다. use Symfony \ Component \ Filesystem \ Filesystem; Symfony \ Component \ Filesystem \ Exception \ IOExceptionInterface를 사용하십시오.
$ fileSystem = new Filesystem ();을 확인하십시오. if ($ fileSystem-> exists ( 'path_to_file') == true) {...