99 votes

Comment vérifier l'existence d'un fichier distant en utilisant PHP ?

Le meilleur que j'ai pu trouver, un if fclose fopen qui 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.

151voto

Brett Dietrich Points 106

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);

De toute façon, vous n'économisez que le coût du transfert HTTP, pas l'établissement et la fermeture de la connexion TCP. Et comme les favicons sont petites, vous ne verrez peut-être pas une grande amélioration.

La mise en cache locale du résultat semble être 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, timestamp ]. Vous pouvez ensuite comparer l'horodatage et recharger le favicon.

67voto

Tom Haigh Points 32314

Comme le dit Pies, vous pouvez utiliser cURL. Vous pouvez faire en sorte que cURL ne vous donne que les en-têtes, et non le corps de la requête, ce qui pourrait rendre le processus plus rapide. Un mauvais domaine peut toujours prendre un certain temps parce que vous attendez que la requête soit terminée ; vous pouvez probablement modifier la durée du délai d'attente 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';   
}

40voto

luBar Points 179

La solution de CoolGoose est bonne mais celle-ci est plus rapide pour les gros fichiers (car elle n'essaie de lire qu'un seul octet) :

if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) {
    $image = $default_image;
}

31voto

Mala Points 4197

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 de récupérer directement le favicon du site (ce qui est un vrai casse-tête puisqu'il peut 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]">

C'est fait.

21voto

Pedro Lobito Points 6794

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
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X