Publié le 07/03/2012
Auteur fobec
Réseaux sociaux
0 partages
0 tweets
0 plus
2 commentaires

Telecharger un fichier distant et l'enregistrer en local

Plusieurs fonctions PHP permettent d'enregistrer un fichier distant sur son poste de travail, par exemple file_get_contents(). La class DownloadBinaryFile reprend le même principe en utilisant l'extension cURL.

Telecharger un fichier avec PHP

Pour télécharger une image, une page HTML ou encore une vidéo, le script PHP procède de la manière suivante:
1. la fonction load() charge le contenu du lien $remote dans un tampon mémoire,
2. avec la fonction saveTo(), le contenu du tampon est enregistré dans un fichier $local.
Attention: si un fichier du même nom existe dans le répertoire local, le fichier est automatiquement supprimé par la fonction unlink().
<?php
/**
 * DownloadBinaryFile: Charger un fichier distant et l'enregistrer en local
 *
 * @author Fobec.com 2012
 * @copyright http://www.fobec.com/php5/1113/telecharger-fichier-distant-enregistrer-local.html 
 */
 
class DownloadBinaryFile {
 
    private $UA="Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2";
    private $REFERER="";
 
    private $rawdata='';
 
/**
 * Télecharger un fichier distant
 * Les données sont stockées dans le tampon $rawdata
 * @param string $url
 * @return boolean
 */
    public function load($url) {
        $curl = curl_init ();
        curl_setopt ($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        if (!empty($this->UA)) {
            curl_setopt ($curl, CURLOPT_USERAGENT, $this->UA);
        }
        if (!empty($this->REFERER)) {
            curl_setopt($curl, CURLOPT_REFERER, $this->REFERER);
        }
        curl_setopt($curl, CURLOPT_BINARYTRANSFER,1);
        curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
        $this->rawdata=curl_exec($curl);
 
        $httpcode=curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if ($httpcode!=200) {
            return FALSE;
        }
 
        curl_close ($curl);
        return TRUE;
    }
 
/**
 * Enregister les données en local
 * @param string $filename
 */
    public function saveTo($filename) {
        if(file_exists($filename)){
            @unlink($filename);
        }
        $fhandle=fopen($filename, "x");
        if ($fhandle) {
            fwrite($fhandle, $this->rawdata);
            fclose($fhandle);
        } else if (isset($error)) {
            throw new Exception("File reading denied to ".$file." !!!");
        }
    }
 
/**
 * Fixer le user agent pour la requet
 * @param string $ua
 */
    public function setUseragent($ua) {
        $this->UA=$ua;
    }
 
 /**
 * Fixer le referer pour la requet
 * @param string $referer
 */
    public function setReferer($referer) {
        $this->REFERER=$referer;
    }
}
?>

Enregistrer une image

Dans le premier exemple, utilisons la class DownloadBinaryFile pour enregistrer une image. Il suffit de définir les liens pour les variables $local et $remote:
$local: chemin de l'image sur notre poste,
$remote: lien du logo sur le site commentcamarche.net.
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/DownloadBinaryFile.php';
 
$local='/var/www/ccmlogo.png';
$remote='http://static.ccm2.net/www.commentcamarche.net/_skin/_local/img/logo.png?201007091112';
 
$DownloadBinaryFile=new DownloadBinaryFile();
if ($DownloadBinaryFile->load($remote)==TRUE) {
    $DownloadBinaryFile->saveTo($local);
} else {
    echo 'download failed';
}
?>

Enregistrer une page HTML

Voyons comment enregistrer une page HTML sur le même principe. Afin d'éviter un blocage de la part du serveur distant, il est préférable de définir un useragent et un referer avec les fonctions setReferer() et setUseragent().
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/DownloadBinaryFile.php';
 
$local='/var/www/fobec_index.html';
$remote='http://www.fobec.com/index.php';
 
$DownloadBinaryFile=new DownloadBinaryFile();
$DownloadBinaryFile->setReferer('http://www.fobec.com');
$DownloadBinaryFile->setUseragent('exemple DownloadBinaryFile');
if ($DownloadBinaryFile->load($remote)==TRUE) {
    $DownloadBinaryFile->saveTo($local);
} else {
    echo 'download failed';
}
?>

La class est un exemple d'encapsulation des fonctionnalités de l'extension cUrl. Les mêmes fonctions auraient pu etre obtenues avec file_get_contents() ou directement avec les sockets. Bien que l'architecture de la class est simple, ces fonctions sont utilisées sur le site pour télécharger un fichier à partir d'un serveur vers le disque dur.

Ajouter un commentaire

Les champs marqués d'un * sont obligatoires, les adresses emails se sont pas publiées.
avatar roundge

Publié par roundge

le 14/06/2012 à 10:25:56

Bien ! Merci pour cette petite classe en php bien pratique !
J'avais 2000 photos libres de droits à télécharger sur un site, dans un dossier ou les fichiers ne sont pas listés.

Mais les numéros de photos se suivent au pas !
Alors avec une boucle 'for', un nom de fichier on va dire "dynamique", c'est parfait !
Mais il faut penser a augmenter le temps max d'execution, max_execution_time dans le php.ini

Merci !

avatar ghanmitaher

Publié par ghanmitaher

le 21/03/2014 à 17:23:22

Bravo! Vous avez deploye des efforts formidables.

A lire aussi

Réseaux sociaux
Présentation de l'article
Catégorie
php5 - class
Mise a jour
07/03/2012
Visualisation
vu 7406 fois
Public
Internaute
Auteur de la publication
Fobec
Admin
Auteur de 261 articles
|BIO_PSEUDO|
Commentaires récents

Publié par fredouille dans java

Il ne faut pas oublier de mettre aussi System.setErr(printStream); pour ne pas oublier les printStackTrace() declenches par le catch

Publié par max dans java

est que ce framework fonctionne pour une application web ?

Publié par Mohamed dans java

Merci beaucoup j'ai eu un probleme de redimensionnement des images , mes images perdaient leur qualite, ta solution m'a aide pour ca mercii

Publié par Juslin dans java

Ca tombe bien et merci.

Publié par mfranca dans CMS

Bonjour, Excellent outil pour moi, très interessant pour mes recherches en amateur...
Merci pour cette création Olubil
Ciao ciao