내가 찾을 수있는 최선의 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) {...