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 7169 fois
Public
Internaute
Auteur de la publication
Fobec
Admin
Auteur de 261 articles
|BIO_PSEUDO|
Commentaires récents

Publié par y__fe dans java

Impeccable merci !

Publié par Fobec dans CMS

//une variante avec UrlMon
uses
UrlMon;

function GetPageContent(URL: string): string;
var
MyFile: file;
Buf: array[0..14] of Char;
Filename: string;

Publié par mohinfo dans CMS

je vous demande un mini projet delphi pour gérer la base de donnée

Publié par robbie dans tuto

marche pas le code le la boite de confirmation
faut-il inclure: { dans le code ou les enlever? merci d'avance pour la reponse (si possible pas par mail merci)

Publié par fobec dans logiciel

MAJ: mise en cache du FAI et optimisation du script de Geolocalisation.