Accueil du site > Codes > PHP > Upload de fichier

Upload de fichier

jeudi 15 janvier 2009, par arnaud

<?php
/*
Ça fait :
- upload de fichiers dans le dossier
- rajoute -numéro au nom de fichier si il existe déjà
- rajoute .txt aux extensions interdites

- présente les fichiers uploadés au téléchargement
- n'affiche pas les fichiers . ni les extentions php

- petite protection contre les bots

Installation et configuration :
- Créer un dossier et mettre ce fichier dedans nommé index.php
- Donner les droit d'écriture sur le dossier à www-data (ou l'utilisateur du serveur http)
- Sécuriser :
   Avec apache : Créer les fichiers .htaccess et .htpasswd

Require :
- besoin de l'extension php : uploadprogress
- besoin de google en ligne (http://ajax.googleapis.com)

Pour le .htaccess :

php_value memory_limit 250M
php_value post_max_size "250M"
php_value upload_max_filesize "250M"

AuthName "ESPACE PROTEGE"
AuthUserFile /var/www/upload/.htpasswd
AuthGroupFile /dev/null
AuthType Basic
<limit GET POST>
        require valid-user
</Limit>

Et la création du .htpasswd :
htpasswd -c .htpasswd utilisateur

Écrit par Arnaud Cordier arnaud [AT] arnaudcordier.org
Distribué sous licence GPL
*/

// LES EXTENTIONS INTERDITES
$noext = array('html','htm','php','php3','php4','php5',);

// UPLOADMETER
if ( ( $id = $_GET['id'] ) !== NULL ) {
        $info = uploadprogress_get_info($id);
        if ($info) {
                $pc = intval($info['bytes_uploaded'] / $info['bytes_total'] * 100);
                $uploaded = intval($info['bytes_uploaded']/1024);
                $total = intval($info['bytes_total']/1024);
                $moy = intval($info['speed_average']/1024);
                if ($info['speed_average']>0)
                        $timeleft = intval(($info['bytes_total'] - $info['bytes_uploaded']) / $info['speed_average']);
$ret = <<<A
<div style='width:100%;height:20px;background-color:red;'>
        <div style='width:$pc%;height:20px;background-color:green;'></div>
</div>
Vitesse moyenne: $moy ko/s<br/>
Chargé: $uploaded / $total ko<br/>
Temps restant: $timeleft secondes<br/>
<script type='text/javascript'>
        jQuery.video_timeout = setTimeout(video_upload_refresh,2000);
</script>
A;
        } else {
$ret = <<<A
<script type='text/javascript'>
        video_upload_stop('$id');
</script>
A;
        }
        header('content-type:text/html; charset=utf-8');
        echo $ret;
        exit;
}

$titre = preg_replace("/.*\//","",getcwd());

// TESTER LES DROITS D'ÉCRITURE DU DOSSIER
if (!is_writable(".")) {
        $error = "<h2 style='color:red;'>Gros problème d'installation, impossible d'écrire dans .</h2>";
}

// PRENDRE EN CHARGE LE FICHIER CHARGÉ
if ( $_FILES['fichier'] AND $_GET['nobot'] == '' ) {
        if ( $_FILES["fichier"]["error"] == UPLOAD_ERR_OK AND is_uploaded_file($_FILES['fichier']['tmp_name'])) {
                preg_match("/(.*)\.([^.]*)/",$_FILES['fichier']['name'],$m);
                $f = $m[1] ? $m[1] : $_FILES['fichier']['name'];
                $ext = $m[2] ? $m[2] : "ext";
                if (in_array($ext,$noext)) {
                        $f = "$f.$ext";
                        $ext = "txt";
                }
                if (file_exists("./".($file = $f.".$ext")))
                        while (file_exists("./".($file = $f."-".(++$i).".$ext")));
                move_uploaded_file($_FILES['fichier']['tmp_name'], "./".$file);
                header("location: .");
        } else {
                $errors[1] = "Fichier trop gros pour php.ini";
                $errors[2] = "Fichier trop gros pour la page";
                $errors[3] = "Fichier pas arrivé en entier";
                $errors[4] = "Pas de fichier...";
                $errors[6] = "Pas de dossier temporaire...";
                $errors[7] = "Écriture impossible sur le disque";
                $errors[8] = "Extension du fichier interdite";
                $error = "<h2 style='color:red;'>Une erreur c'est produite: ".$errors[$_FILES['fichier']['error']]."</h2>";
        }
}

// LISTE DES FICHIERS TÉLÉCHARGEABLES
$dh = opendir('.');
while (false !== ($file = readdir($dh))) {
        if (strpos($file,".php")==false && strpos($file,".")!==0 && is_file($file))
                $files[] = "<a href='$file'>$file</a>";
}
if ($files) {
        $files = join("<br/>",$files);
$files = <<<A
        <h2>Les fichiers à télécharger</h2>
        <p>$files</p>
A;
}

// TAILLE MAX
$max_upload = ini_get('upload_max_filesize');

// LA PAGE HTML
header('content-type:text/html; charset=utf-8');
echo <<<A
<html>
<head>
<title>$titre</title>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js' type='text/javascript'></script>
<script type='text/javascript'>
jQuery(function($) {
        upload_cpt = 0;
        doc_form = jQuery('.form_upload');
        jQuery('.form_upload').each( function() {
                var formulaire = jQuery(this);
                var upload_id = "upload_id";
                var upload_bouton = formulaire.find('input[@type="submit"]').eq(0);
                if (upload_id && upload_bouton) {
                        var upload_hidden = jQuery("<input type='hidden' name='UPLOAD_IDENTIFIER' value='"+upload_id+"'/>").prependTo(formulaire);
                        var upload_cpt = 0;
                        upload_bouton.bind('click',function() {
                                upload_hidden.attr("value",upload_id+'_'+(++upload_cpt));
                                video_upload_start(jQuery("<div class='video_meter' style='width:400px;'>").insertAfter(formulaire),upload_hidden.attr("value"));
                        });
                }
        } );
});
//+ lance la barre de progression
function video_upload_start(meter,id) {
        meter.attr('id','meter'+id);
        jQuery.video_timeout = setTimeout(video_upload_refresh,3000);
        return true;
}
//+ met à jour la barre de progression
function video_upload_refresh() {
        jQuery('.video_meter').each(function(){
                var meter = jQuery(this);
                var id = this.id.replace(/meter/,'');
                if (id) {
                        var url = 'index.php?id='+id;
                        jQuery.get(url,{dataType:'html'}, function(data) {
                                meter.html(data);
                        });
                }
        });
}
//+ stop la barre
function video_upload_stop(id) {
        jQuery('#meter'+id).remove();
}
</script>
</head>
<body>
$error
$files
<h2>Envoyer un nouveau fichier</h2>
<form method="post" class="form_upload" enctype="multipart/form-data" action='.'>
        <input type="file" name="fichier"/>
        <p style="display:none">
                Ne surtout rien écrire ici, c'est juste un truc anti-bot
                <input type="text" name="nobot" value=""/>
        </p>
        <input type="submit" name="envoyer" value="envoyer"/>
</form>
(Taille maximum: $max_upload)
</body>
</html>
A;

?>

Documents joints

  • upload.tgz (TGZ – 2.9 ko)

    Un dossier upload avec le fichier php et le .htaccess et un .htpasswd déjà prêt.

    L’utilisateur de démonstration est "charles" son mot de passe est "gement".

    L’archive est une tarball car elle permet de préserver les droits sur les fichiers.

Répondre à cet article

SPIP | | Plan du site | Suivre la vie du site RSS 2.0 | Site hébergé chez Mutins