Classe d'upload de fichier php

Soyez le premier à donner votre avis sur cette source.

Vue 5 369 fois - Téléchargée 596 fois

Description

Bonjour,

Je viens de refaire ma classe d'upload de fichiers et souhaite vous la faire partager.
Elle gère
-la création de l'arborescence de fichiers,
-control de l'extension,
-la gestion du nouveau nom de fichier (unique, avec préfixe ou non, etc),
-les erreurs d'upload et de configuration.
-detection automatique d'un fichier image et peut appliquer un control sur sa taille si setMaxDimensions est définie.
La source contient qu'un seul fichier, celui de la classe:
class.UploadFile.php

Le fichier contient l'exemple d'utilisation à la fin. Vous pouvez tout simplement executer ce fichier sur votre serveur pour tester.

Source / Exemple :


<?php
class UploadFile  {
    
    private $droits = 0755;
    private $poidMax = 2;
    private $postFile;
    private $type = array();
    private $path;
    private $prefixeName;
    private $name;
	private $extension;
	
	private $maxWidth;
	private $maxHeight;
	
	private $errorUpload;
    
    //SET
	public function setDroits($v) {
		$this->droits = $v;
	}
	public function setPoidMax($v) {
		$this->poidMax = $v;
	}
    public function setPostFile($v) {
        $this->postFile = $v;
    }
    public function setType($v) {
        $this->type = explode("/", $v);
    }
    public function setPath($v) {
        $this->path = $v;
    }
	public function setPrefixeName($v) {
		$this->prefixeName = $v;
	}
    public function setName($v) {
        $this->name = preg_replace('`[^a-zA-Z0-9]+`i', "-", $v);
    }
	public function setMaxDimensions($v, $v2) {
		$this->maxWidth = $v;
		$this->maxHeight = $v2;
	}
    
    //GET
	public function getPath() {
        return $this->path;
    }
	public function getPrefixeName() {
        return $this->prefixeName;
    }
    public function getName() {
        return $this->name;
    }
	public function getExtension() {
		return $this->extension;
	}
	public function getPathFileName() {
		return $this->path."/".$this->prefixeName.$this->name.".".$this->extension;
	}
	public function getErrorUpload() {
		return $this->errorUpload;
	}
    
	//METHOD
    public function upload() {
		if($this->postFile != "") {
			if($this->controls()) {
				if($this->createDir()) {
					$this->uniqName();
					if($this->moveFile()) {
						$this->errorUpload = "<b class=''>SUCCES</b> : Le fichier a bien été téléchargé";
						return true;
					}
				}
			}
		}
		else $this->errorUpload = "<b class=''>ERREUR</b> : La valeur du champs FILE n'a pas été parametrée";
    }
	private function controls() {
		if($this->setErrorUpload())
			if($this->verifSize())
				if($this->verifExtension())
					if($this->verifImage())
						return true;
	}
    private function createDir() {
		if($this->path != "") {
			if(preg_match('`\/`', $this->path)) {
				$path = explode("/", $this->path);
				$newDir = "";
				foreach($path as $dir) {
					if($dir == "..") {
						$newDir .= "../";
						continue;
					}
					if(!file_exists($newDir.$dir))
						mkdir($newDir.$dir, $this->droits); 
						
					$newDir .= $dir."/";
				}
			}
			else if(!file_exists($this->path))
				mkdir($this->path, $this->droits);
				
			return true;
		}
		else {
			$this->errorUpload = "<b class=''>ERREUR</b> : Aucune destination n'a été spécifiée";
			return false;
		}
    }
	private function setErrorUpload() {
		switch ($_FILES[$this->postFile]['error']) {
			case 1:
				$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier est trop volumineux pour la configuration du serveur (upload_max_filesize).";
				break;
			case 2:
				$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier est trop volumineux pour la configuration du serveur (max_file_size).";
				break;
			case 3:
				$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier n'a été que partiellement téléchargé.";
				break;
			case 4:
				$this->errorUpload = "<b class=''>ERREUR</b> : Aucun fichier n'a été téléchargé.";
				break;
			case 6:
				$this->errorUpload = "<b class=''>ERREUR</b> : Un dossier temporaire est manquant.";
				break;
			case 7:
				$this->errorUpload = "<b class=''>ERREUR</b> : Échec de l'écriture du fichier sur le disque.";
				break;
		}
		if($this->errorUpload == "") return true;
	}
	private function verifSize() {
		if(filesize($_FILES[$this->postFile]['tmp_name']) > ($this->poidMax*1024*1024) ) {
			$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier est trop volumineux";
			return false;
		}
		return true;
	}
	private function verifExtension() {
		if(preg_match('`^(.+)\.(.+)+$`i', $_FILES[$this->postFile]['name'], $extension)) {
			$this->extension = strtolower($extension[2]);
			if(is_array($this->type) && !in_array($this->extension, $this->type) ) {
				$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier n'est pas au format demandé";
				return false;
			}
			else {
				if(!$this->verifMimeType($extension[2])) {
					$this->errorUpload = "<b class=''>ERREUR</b> : Le fichier semble être corrompu";
					return false;
				}
			}
			return true;
		}
		return false;
	}
	private function verifMimeType($extension) {
		$mimeType = $_FILES[$this->postFile]['type'];
		switch($extension) {
			//IMG
			case "jpg": case "jpeg": case "jpe":
				if($mimeType == "image/jpeg" || $mimeType == "image/pjpeg") return true; break;
			case "gif": case "gif":
				if($mimeType == "image/gif" || $mimeType == "image/pgif") return true; break;
			case "doc": case "dot":
			//DOC
				if($mimeType == "application/msword") return true; break;
			case "xls": case "xla":
				if($mimeType == "application/msexcel" || $mimeType == "application/vnd.ms-excel") return true; break;
			case "pdf": 
				if($mimeType == "application/pdf") return true; break;
			case "csv": 
				if($mimeType == "text/comma-separated-values") return true; break;
			case "txt": 
				if($mimeType == "text/plain") return true; break;
			case "rft": 
				if($mimeType == "text/richtext") return true; break;
			//ARCHIVE
			case "gz": 
				if($mimeType == "application/gzip") return true; break;
			case "zip": 
				if($mimeType == "application/zip") return true; break;
			//AUDIO
			case "mp2": case "mp3":
				if($mimeType == "audio/x-mpeg") return true; break;
			case "waw":
				if($mimeType == "audio/x-waw") return true; break;
			//VIDEO
			case "mpeg": case "mpg": case "mpe":
				if($mimeType == "video/mpeg") return true; break;
			case "qt": case "ov":
				if($mimeType == "video/quicktime") return true; break;
			case "avi":
				if($mimeType == "video/x-msvideo") return true; break;
			case "movie":
				if($mimeType == "video/x-sgi-movie") return true; break;
		}
		return false;
	}
	private function verifImage() {
		if(preg_match('`^(jpg|jpeg|png|gif)$`', $this->extension)) {
			$img = getimagesize($_FILES[$this->postFile]['tmp_name']);
			if($this->maxWidth != "" || $this->maxHeight != "") {
				if($img[0] > $this->maxWidth || $img[1] > $this->maxHeight) {
					$this->errorUpload = "<b class=''>ERREUR</b> : L'image dépasse les dimensions autorisées";
					return false;
				}
			}
		}
		return true;
	}
	private function uniqName() {
		if($this->name == "") {
			$this->name = $this->prefixeName.uniqid("", true);
		}
	}
	private function moveFile() {
		if(!move_uploaded_file($_FILES[$this->postFile]['tmp_name'], $this->path."/".$this->prefixeName.$this->name.".".$this->extension)) {
			$this->errorUpload = "<b class=''>ERREUR</b> : Le transfert du fichier a échoué";
			return false;
		}
		return true;
	}
}
if(isset($_FILES['file'])) {
    $upload = new UploadFile();               //Instanciation
    $upload->setPostFile("file");             //Nom du INPUT FILE (name)
    $upload->setType("jpg");                  //Extension(s) autorisee(s) - string, separer par / les differentes extensions ex:"doc/gif/jpeg"
    $upload->setPath("UPLOAD/1");             //Chemin d'upload - les retours avec "../" sont acceptes
    $upload->upload();
	echo $upload->getErrorUpload();
}
?>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="upload" />
</form>

Conclusion :


Cette classe a également été réalisée en vue d'etre couplée avec ma future classe de redimentionnement d'images (crop divers etc...), a bon entendeur!^^

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
496
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
29 juillet 2009
1
joli boulot :-D
Messages postés
381
Date d'inscription
lundi 12 novembre 2007
Statut
Membre
Dernière intervention
23 octobre 2014

Pour les commentaires je pensais plus aux personnes qui utilisent un I.D.E. pour avoir l'autocompletion d'active. Mais aussi pour le dev', lorsque on laisse de côté un code pendant quelques temps de pouvoir le modifié sans trop se casser la tête.

++
Messages postés
35
Date d'inscription
lundi 10 avril 2006
Statut
Membre
Dernière intervention
21 mai 2010

J'ai mis dans ma classe les type-mime les plus courants, à chacun d'adapter cette liste selon ses besoins et c'est d'ailleurs pour cela que j'ai également fourni une liste de type-mime. Une fois que cela est fait, la déclaration se fait en une seule ligne, pour chaque upload.

$upload->setType("jpg/doc/xls");

Pour ce qui est des commentaires, j'ai commenté l'exemple d'utilisation. Les gens qui veulent utiliser cette classe peuvent me poser toutes les questions qu'ils veulent au besoin.
Messages postés
381
Date d'inscription
lundi 12 novembre 2007
Statut
Membre
Dernière intervention
23 octobre 2014

Bonjour,

Je n'aurais pas fait la vérification du type-mime comme cela. Tout est codé en dur dans votre classe, admettons que je veuille envoyé un .rar et que je ne veux pas ajouter de ligne de code dans la class. Comment faire ?

Je mettrais en paramètre lors de l'instanciation de la class un tableau de type-mime autorisés puis de boucler sur ce tableau pour vérifier si le fichier est autorisé. C'est un peu plus souple et évolutif je pense que tout en "dur".

Deuxième chose, il faudrait commenter également votre code : j'utilise pour référence la documentation du zendframwork http://framework.zend.com/manual/fr/coding-standard.html

Cordialement
Messages postés
35
Date d'inscription
lundi 10 avril 2006
Statut
Membre
Dernière intervention
21 mai 2010

Au fait, je file un lien pour gérer des extensions moins courantes pour ce fameux type-mime:

http://fr.selfhtml.org/divers/typesmime.htm
Afficher les 13 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.