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

Publié par Amal dans tuto

pour moi j'ai créé une liste déroulante en liaisant avec la base de donnée déja existant mais la valeur sélectionné ne peut pas etre afficher jamais et...

Publié par Jacques dans CMS

Cette méthode produit une gamme de gris qui ne tient pas compte des caractéristiques de la vision humaine.
En vidéo on utilise la fonction luminance qui représente mieux les jaunes e...

Publié par Patrice dans tuto

Bonjour

je cherche a activer mod_headers chez 1and1, impossible de mettre mes jpg en cache, auriez vous une piste ? merci !

Publié par mido dans java

si je veut extraire les liens a partir de google searche c'est a dire utiliser la raquette suivante "http://www.google.tn/search?q=" avec java bien sur ..merci d'avance :)

Publié par Romaingineer dans tuto

Question un peu similaire celle de nicolasterraes.

Je ne trouve pas de ligne dans wpcontentthemes, j'en trouve 2 ou trois dans WP includes mais qui utilsent la fonction echo...

Du coup...