Le meilleur que j'ai pu trouver, un if
fclose
fopen
type de chose, fait que la page se charge très lentement.
En gros, ce que j'essaie de faire est le suivant: j'ai une liste de sites Web et je veux afficher leurs favicons à côté d'eux. Cependant, si un site n'en a pas, j'aimerais le remplacer par une autre image plutôt que d'afficher une image cassée.
onerror
image, par exemple une solution utilisant jQueryRéponses:
Vous pouvez demander à curl d'utiliser la méthode HTTP HEAD via CURLOPT_NOBODY.
Plus ou moins
$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);
Quoi qu'il en soit, vous économisez uniquement le coût du transfert HTTP, pas l'établissement et la fermeture de la connexion TCP. Et comme les favicons sont petites, vous pourriez ne pas voir beaucoup d'amélioration.
La mise en cache du résultat localement semble une bonne idée si elle s'avère trop lente. HEAD vérifie l'heure du fichier et la renvoie dans les en-têtes. Vous pouvez faire comme les navigateurs et obtenir le CURLINFO_FILETIME de l'icône. Dans votre cache, vous pouvez stocker l'URL => [favicon, horodatage]. Vous pouvez ensuite comparer l'horodatage et recharger le favicon.
la source
retcode
erreurs sur les 400 codes donc la validation ne serait>=
pas juste>
Comme Pies le dit, vous pouvez utiliser cURL. Vous pouvez demander à cURL de ne vous donner que les en-têtes, et non le corps, ce qui pourrait le rendre plus rapide. Un domaine défectueux peut toujours prendre un certain temps car vous attendez que la demande expire; vous pouvez probablement modifier la durée du délai d'expiration en utilisant cURL.
Voici un exemple:
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'; }
la source
La solution de CoolGoose est bonne mais c'est plus rapide pour les gros fichiers (car il essaie de lire seulement 1 octet):
if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) { $image = $default_image; }
la source
fopen
- si le code de retour de la demande est 404, fopen renvoie false.Ce n'est pas une réponse à votre question initiale, mais une meilleure façon de faire ce que vous essayez de faire:
Au lieu d'essayer d'obtenir directement le favicon du site (ce qui est une douleur royale étant donné qu'il pourrait s'agir de /favicon.png, /favicon.ico, /favicon.gif ou même /path/to/favicon.png), utilisez google:
<img src="http://www.google.com/s2/favicons?domain=[domain]">
Terminé.
la source
Une fonction complète de la réponse la plus votée:
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;} }
Vous pouvez l'utiliser comme ceci:
if(remote_file_exists($url)) { //file exists, do something }
la source
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
. J'ai mis à jour la réponse pour gérer les302
redirections.Si vous utilisez des images, utilisez getimagesize. Contrairement à file_exists, cette fonction intégrée prend en charge les fichiers distants. Il renverra un tableau contenant les informations de l'image (largeur, hauteur, type..etc). Tout ce que vous avez à faire est de vérifier le premier élément du tableau (la largeur). utilisez print_r pour afficher le contenu du tableau
$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"; }
la source
@
devantgetimagesize
, mais en me sentant coupable de ce hack.exif_imagetype
, et c'est beaucoup plus rapide stackoverflow.com/a/38295345/1250044Cela peut être fait en obtenant le code d'état HTTP (404 = introuvable), ce qui est possible avec
file_get_contents
Docs en utilisant les options de contexte. Le code suivant prend en compte les redirections et renverra le code de statut de la destination finale ( Démo ):$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";
Si vous ne souhaitez pas suivre les redirections, vous pouvez le faire de la même manière ( Démo ):
$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";
Certaines des fonctions, options et variables utilisées sont expliquées plus en détail dans un article de blog que j'ai écrit: HEAD first with PHP Streams .
la source
$http_response_header
consultez php.net/manual/en/reserved.variables.httpresponseheader.php .if (false === file_get_contents("http://example.com/path/to/image")) { $image = $default_image; }
Devrait marcher ;)
la source
Les fonctions intégrées de PHP peuvent ne pas fonctionner pour vérifier l'URL si le paramètre allow_url_fopen est désactivé pour des raisons de sécurité. Curl est une meilleure option car nous n'aurions pas besoin de changer notre code ultérieurement. Voici le code que j'ai utilisé pour vérifier une URL valide:
$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; }
Veuillez noter l' option CURLOPT_SSL_VERIFYPEER qui vérifie également les URL commençant par HTTPS.
la source
Pour vérifier l'existence d'images,
exif_imagetype
devrait être préférégetimagesize
, car il est beaucoup plus rapide.Pour supprimer le
E_NOTICE
, ajoutez simplement l'opérateur de contrôle d'erreur (@
).if (@exif_imagetype($filename)) { // Image exist }
En prime, avec la valeur retournée (
IMAGETYPE_XXX
) deexif_imagetype
nous pourrions également obtenir le type mime ou l'extension de fichier avecimage_type_to_mime_type
/image_type_to_extension
.la source
Une solution radicale serait d'afficher les favicons comme images d'arrière-plan dans un div au-dessus de votre icône par défaut. De cette façon, tous les frais généraux seraient placés sur le client tout en n'affichant toujours pas les images cassées (les images d'arrière-plan manquantes sont ignorées dans tous les navigateurs AFAIK).
la source
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!!!"; }
la source
Vous pouvez utiliser les éléments suivants:
$file = 'http://mysite.co.za/images/favicon.ico'; $file_exists = (@fopen($file, "r")) ? true : false;
A travaillé pour moi en essayant de vérifier si une image existe sur l'URL
la source
Vous pouvez utiliser :
$url=getimagesize(“http://www.flickr.com/photos/27505599@N07/2564389539/”); if(!is_array($url)) { $default_image =”…/directoryFolder/junal.jpg”; }
la source
Cela fonctionne pour moi pour vérifier si un fichier distant existe en 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'; }
la source
Vous devez émettre des requêtes HEAD, pas GET one, car vous n'avez pas du tout besoin du contenu de l'URI. Comme Pies l'a dit ci-dessus, vous devez vérifier le code d'état (dans les plages 200-299, et vous pouvez éventuellement suivre les redirections 3xx).
La question des réponses contient de nombreux exemples de code qui peuvent être utiles: PHP / Curl: HEAD La requête prend beaucoup de temps sur certains sites
la source
Il existe une alternative encore plus sophistiquée. Vous pouvez faire la vérification de tout côté client en utilisant une astuce 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); }; });
De http://snipplr.com/view/18782/add-a-favicon-near-external-links-with-jquery/ (le blog original est actuellement en panne)
la source
toutes les réponses ici qui utilisent get_headers () font une requête GET. Il est beaucoup plus rapide / moins cher de faire une requête HEAD.
Pour vous assurer que get_headers () effectue une requête HEAD au lieu d'un GET, vous devez ajouter ceci:
stream_context_set_default( array( 'http' => array( 'method' => 'HEAD' ) ) );
donc pour vérifier si un fichier existe, votre code ressemblerait à ceci:
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 retournera soit faux soit vrai, évidemment.
la source
Je ne sais pas si celui-ci est plus rapide lorsque le fichier n'existe pas à distance, is_file () , mais vous pourriez essayer .
$favIcon = 'default FavIcon'; if(is_file($remotePath)) { $favIcon = file_get_contents($remotePath); }
la source
var_dump(is_file('http://cdn.sstatic.net/stackoverflow/img/sprites.png')); bool(false)
Si le fichier n'est pas hébergé en externe, vous pouvez traduire l'URL distante en un chemin absolu sur votre serveur Web. De cette façon, vous n'avez pas besoin d'appeler CURL ou file_get_contents, etc.
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' );
la source
Si vous utilisez le framework Symfony, il existe également un moyen beaucoup plus simple d'utiliser le
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; }
La documentation pour HttpClient est également très bonne et vaut peut-être la peine d'être examinée si vous avez besoin d'une approche plus spécifique: https://symfony.com/doc/current/http_client.html
la source
Vous pouvez utiliser le système de fichiers: utilisez Symfony \ Component \ Filesystem \ Filesystem; utilisez Symfony \ Component \ Filesystem \ Exception \ IOExceptionInterface;
et vérifiez $ fileSystem = new Filesystem (); if ($ fileSystem-> existe ('path_to_file') == true) {...
la source