begin process at 2008 07 21 00:34:37
1 213 530 membres
431 nouveaux aujourd'hui
14 167 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

[PHP5] - CLASSE D'UPLOAD


Information sur la source

Catégorie :Class et Objet ( POO ) Classé sous : upload, classe, php5, securite, file Niveau : Débutant Date de création : 18/01/2008 Date de mise à jour : 20/04/2008 16:00:21 Vu : 4 583

Note :
8 / 10 - par 2 personnes
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (20)
Ajouter un commentaire et/ou une note

Description

Oui je sais, ca fait encore une de plus ! :)
Mais personnellement je n'ai rien trouvé qui me convienne en Php5.

Cette classe essaye au maximum d'éviter des attaques lors de l'upload : gestion des erreurs retournées par http, vérification de la taille avec filesize, aboli l'usage de caractères dangeureux (permettant des actions pas très saines !), et vérification de toutes les étapes importantes lors du transfert.

De plus vous avez la possibilité de choisir si vous voulez déposer le fichier dans un endroit particulier, avec un nom particulier, si vous voulez créer les dossiers et sous dossiers ou ira votre fichier, si vous souhaitez renommer le fichier s'il existe déjà un fichier du même nom, et si vous voulez avoir un fichier ayant un nom propre (alphanumérique, ., _ et -)

Regardez la source pour plus de compréhension :)

Source

  • <?php
  • /**
  • * @name SpecialException
  • * @filesource SpecialException.php
  • *
  • * @author Cyril Nicodème
  • * @license Gnu/Agpl
  • * @version 0.1
  • *
  • * @since 18/01/2008
  • */
  • class SpecialException extends Exception {
  • public function __construct ($iCode, $iParameter = null) {
  • // Ici vous pouvez appeler un fichier xml pour aller dans le noeud __lang__>Class>Code
  • // Class étant la classe à l'origine de l'erreur
  • // Et le code le code retourné par l'erreur
  • // Comme cela vous disposez d'une gestion d'erreur multilangue
  • // C'est qu'une idée, c'est pour ca que je n'ai mis que des commentaires, que vous adaptiez la classe à vos besoins ! :)
  • }
  • }
  • ?>
  • <?php
  • /**
  • * @name InvalidParameterException
  • * @filesource InvalidParameterException.php
  • *
  • * @author Cyril Nicodème
  • * @license Gnu/Agpl
  • * @version 0.1
  • *
  • * @since 18/01/2008
  • */
  • class InvalidParameterException extends SpecialException {
  • const BOOLEAN_NEEDED = 0;
  • const INT_NEEDED = 1;
  • const STRING_NEEEDED = 2;
  • const ARRAY_NEEDED = 4;
  • const RESOURCE_NEEDED = 8;
  • const OBJECT_NEEDED = 16;
  • const INVALID_KEY = 32;
  • }
  • ?>
  • <?php
  • define ('DIR_S', DIRECTORY_SEPARATOR);
  • /**
  • * @name UploadException
  • */
  • class UploadException extends SpecialException {};
  • /**
  • * @name Upload
  • * @filesource Upload.php
  • *
  • * @author Cyril Nicodème
  • * @license Gnu/Agpl
  • * @version 0.1
  • *
  • * @since 12/01/2008
  • */
  • class UploadHelper {
  • /**
  • * @property Constants of designed error
  • */
  • const UNAUTHORIZED_FORM_SIZE = 1; // The file size is over the form authorized size
  • const UNAUTHORIZED_SIZE = 2; // The file size is over the authorized size
  • const UNALLOWED_EXTENSION = 3; // The file does not have an authorized extension
  • const ILLEGAL_FILE_NAME = 4; // The file contains Illegal Characters
  • const INCOMPLETE_FILE = 10; // The file was not completely uploaded
  • const UNUPLOADED_FILE = 11; // No file was uploaded
  • const INVALID_FILE = 12; // The file is not a valid uploaded file
  • const INVALID_IMAGE_FILE = 13; // The file is not a valid Image File
  • const UNABLE_CREATE_FOLDER = 20; // Unable to create a subfolder
  • const INEXISTANT_DESTINATION = 21; // Destination Folder does not exists !
  • const EXISTANT_FILE = 22; // The file already exists
  • const INEXISTANT_FILE = 23; // The file does not exists
  • const UNABLE_TO_MOVE = 24; // Unable to upload the file. Maybe you haven\'t to write into the folder ?
  • /**
  • * @var Array $_aParameters
  • * Contain all the parameters
  • */
  • private $_aParameters = array (
  • // @var String : Contain the Path to the destination folder
  • 'destinationFolder' => '',
  • // @var String : Contain the name of the file
  • 'fileName' => '',
  • // @var String : Contain the destination folder + the file name
  • 'filePath' => '',
  • // @var Array : Contain an array of Allowed extensions. If it's an empty array, all the extensions will be allowed
  • 'allowedExt' => array (),
  • // @var boolean : Indicate if we rename the file (if already exists) or not
  • 'rename' => false,
  • // @var boolean : Indicate if we cleaning the file from strange characters (allow only alphanumeric, ., - and _)
  • 'cleanFileName' => false,
  • // @var boolean : Indicate if we create the subfolder for the destinationFolder value
  • 'createSubFolders' => true,
  • // @var int : Indicate the max file size for the uploaded file
  • 'maxFileSize' => 0,
  • // @var boolean : Indicate if we need to check if the file is an image
  • 'isImage' => false);
  • /**
  • * @name __set
  • * Modify the values : destinationFolder, fileName, filePath, allowedExt, rename, cleanFileName, createSubFolders, maxFileSize, isImage
  • *
  • * @param String $sKey
  • * @param Mixed (String, Array, Boolean) $mValue
  • *
  • * @return void
  • */
  • public function __set ($sKey, $mValue) {
  • if (!is_string ($sKey))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • switch (strtolower ($sKey)) {
  • case 'destinationfolder':
  • if (!is_string ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
  • $mValue = str_replace(array ("\\", "/"), DIR_S, $mValue);
  • if (substr ($mValue, -1) != DIR_S)
  • $mValue .= DIR_S;
  • $this->_aParameters['destinationFolder'] = $mValue;
  • break;
  • case 'filename':
  • if (!is_string ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
  • $this->_aParameters['fileName'] = $mValue;
  • break;
  • case 'filepath':
  • if (!is_string ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
  • $mValue = str_replace(array ("\\", "/"), DIR_S, $mValue);
  • $this->_aParameters['destinationFolder'] = substr ($mValue, 0, strrpos ($mValue, DIR_S)+1);
  • $this->_aParameters['fileName'] = substr ($mValue, strrpos ($mValue, DIR_S)+1);
  • $this->_aParameters['filePath'] = $mValue;
  • break;
  • case 'allowedext':
  • if (!is_array ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::ARRAY_NEEEDED, 2);
  • $this->_aParameters['allowedExt'] = $mValue;
  • break;
  • case 'rename':
  • if (!is_bool ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
  • $this->_aParameters['rename'] = $mValue;
  • break;
  • case 'cleanfilename':
  • if (!is_bool ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
  • $this->_aParameters['cleanFileName'] = $mValue;
  • break;
  • case 'createsubfolders':
  • if (!is_bool ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
  • $this->_aParameters['createSubFolders'] = $mValue;
  • break;
  • case 'maxfilesize':
  • if (!is_int ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::INT_NEEDED, 2);
  • $this->_aParameters['maxFileSize'] = $mValue;
  • break;
  • case 'isimage':
  • if (!is_bool ($mValue))
  • throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
  • $this->_aParameters['isImage'] = $mValue;
  • break;
  • default:
  • throw new InvalidParameterException (InvalidParameterException::INVALID_KEY, $sKey);
  • }
  • }
  • /**
  • * @name __get
  • * Get the values : destinationFolder, fileName, filePath, allowedExt, rename, cleanFileName, createSubFolders, maxFileSize, isImage
  • *
  • * @param String $sKey
  • *
  • * @return Mixed (String, Array, Boolean)
  • */
  • public function __get ($sKey) {
  • if (!is_string ($sKey))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • if (isset ($this->_aParameters [$sKey]))
  • return $this->_aParameters [$sKey];
  • else
  • throw new InvalidParameterException (InvalidParameterException::INVALID_KEY, $sKey);
  • }
  • /**
  • * @name addAllowedExtension
  • * Add a specific extension or an array of extensions
  • *
  • * @param Mixed (Array, String) $mValue
  • *
  • * @return void
  • */
  • public function addAllowedExtension ($mValue) {
  • if (is_array ($mValue))
  • $this->_aParameters['allowedExt'] = array_merge ($this->_aParameters['allowedExt'], $mValue);
  • elseif (is_string ($mValue))
  • $this->_aParameters['allowedExt'] [] = $mValue;
  • else
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED + InvalidParameterException::ARRAY_NEEEDED, 1);
  • }
  • /**
  • * @name cleanAllowedExtension
  • * Set the $_aAllowedExt array empty
  • *
  • * @return void
  • */
  • public function cleanAllowedExtension () {
  • $this->_aParameters['allowedExt'] = array ();
  • }
  • /**
  • * @name createSubFolders
  • * Create sub folders from a specific path or from the $_sDestinationFolder
  • *
  • * @param String $sFolderToCreate (optional)
  • *
  • * @return void
  • */
  • public function createSubFolders ($sFolderToCreate=null) {
  • if (isset ($sFolderToCreate) && !is_string ($sFolderToCreate))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • if (!isset ($sFolderToCreate))
  • $sFolderToCreate = $this->_aParameters['destinationFolder'];
  • $aFolders = explode (DIR_S, $sFolderToCreate);
  • $sFinalFolder = '';
  • foreach ($aFolders as $sFolder) {
  • $sFinalFolder .= $sFolder.DIR_S;
  • if (!is_dir ($sFinalFolder)) {
  • if (!mkdir ($sFinalFolder))
  • throw new UploadException (UploadHelper::UNABLE_CREATE_FOLDER);
  • }
  • }
  • }
  • /**
  • * @name cleanFileName
  • * Modify the value to be only alphanumeric, _, - and .
  • *
  • * @param String $sFileName
  • *
  • * @return String
  • */
  • public function cleanFileName ($sFileName) {
  • if (!is_string ($sFileName))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • $aSearch = array ('#à|â|ä#i', '#é|è|ê|ë#i', '#î|ï#i', '#ô|ö#i', '#ù|û|ü#i', '#ç#i', '#&#i', '#@#i', "# |'#", '#"#', '#[^a-zA-Z0-9_\.-]*#i');
  • $aReplace = array('a', 'e', 'i', 'o', 'u', 'c', '_and_', 'at', '_');
  • return preg_replace($aSearch, $aReplace, strtolower($sFileName));
  • }
  • /**
  • * @name renameFile
  • * Rename a specific value while the file from the given file path exists and return the new file path
  • *
  • * @param String $sFilePath
  • *
  • * @return String
  • */
  • public function renameFile ($sFilePath) {
  • if (!is_string ($sFilePath))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • $sFileName = substr ($sFilePath, strrpos ($sFilePath, DIR_S)+1);
  • $sDestinationFolder = substr ($sFilePath, 0, strrpos ($sFilePath, DIR_S)+1);
  • $sBaseName = substr ($sFileName, 0, strrpos ($sFileName, '.'));
  • $sExtension = '.'.preg_replace ('`.*\.([^\.]*)$`', '$1', $sFileName);
  • $sAdd = '';
  • $iWhile = 0;
  • while (file_exists ($sDestinationFolder.$sBaseName.$sAdd.$sExtension)) {
  • $sAdd = '('.$iWhile.')';
  • $iWhile++;
  • }
  • return $sDestinationFolder.$sBaseName.$sAdd.$sExtension;
  • }
  • /**
  • * @name isImage
  • * Get if the file is an image or not
  • *
  • * @param String $sFilePath
  • *
  • * @return Boolean
  • */
  • public function isImage ($sFilePath) {
  • if (!is_string ($sFilePath))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • if (!file_exists ($sFilePath))
  • throw new UploadException (UploadHelper::INEXISTANT_FILE);
  • $aParams = @getimagesize($sFilePath);
  • /*
  • * 1 = IMAGETYPE_GIF
  • * 2 = IMAGETYPE_JPEG
  • * 3 = IMAGETYPE_PNG
  • * 4 = IMAGETYPE_SWF
  • * 5 = IMAGETYPE_PSD
  • * 6 = IMAGETYPE_BMP
  • * 7 = IMAGETYPE_TIFF_II (ordre d'octets d'Intel)
  • * 8 = IMAGETYPE_TIFF_MM (ordre d'octets Motorola)
  • * 9 = IMAGETYPE_JPC
  • * 10 = IMAGETYPE_JP2
  • * 11 = IMAGETYPE_JPX
  • * 12 = IMAGETYPE_JB2
  • * 13 = IMAGETYPE_SWC
  • * 14 = IMAGETYPE_IFF
  • * 15 = IMAGETYPE_WBMP
  • * 16 = IMAGETYPE_XBM
  • */
  • if (!isset ($aParams[2]))
  • return false;
  • elseif ($aParams[2] > 0 && $aParams[2] < 16)
  • return true;
  • else
  • return false;
  • }
  • /**
  • * @name upload
  • * Upload the file given into the $_sDestinationFolder given and return the file path
  • *
  • * @param Array $aSubmittedFile
  • *
  • * @return String
  • */
  • public function upload ($aSubmittedFile) {
  • if (!is_array ($aSubmittedFile))
  • throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
  • if ($aSubmittedFile['error'] == UPLOAD_ERR_INI_SIZE)
  • throw new UploadException (UploadHelper::UNAUTHORIZED_SIZE);
  • if ($aSubmittedFile['error'] == UPLOAD_ERR_FORM_SIZE)
  • throw new UploadException (UploadHelper::UNAUTHORIZED_FORM_SIZE);
  • if ($aSubmittedFile['error'] == UPLOAD_ERR_PARTIAL)
  • throw new UploadException (UploadHelper::INCOMPLETE_FILE);
  • if ($aSubmittedFile['error'] == UPLOAD_ERR_NO_FILE)
  • throw new UploadException (UploadHelper::UNUPLOADED_FILE);
  • if (!is_uploaded_file ($aSubmittedFile['tmp_name']))
  • throw new UploadException (UploadHelper::INVALID_FILE);
  • if (isset ($this->_aParameters['maxFileSize']) && filesize ($aSubmittedFile['tmp_name']) > $this->_aParameters['maxFileSize'])
  • throw new UploadException (UploadHelper::UNAUTHORIZED_SIZE);
  • if (preg_match('#[\x00-\x1F\x7F-\x9F/\\\\]#', $aSubmittedFile['name']))
  • throw new UploadException (UploadHelper::ILLEGAL_FILE_NAME);
  • if ((count ($this->_aParameters['allowedExt']) > 0) &&
  • !(in_array (preg_replace ('`.*\.([^\.]*)$`', '$1', $aSubmittedFile['name']), $this->_aParameters['allowedExt'])))
  • throw new UploadException (UploadHelper::UNALLOWED_EXTENSION);
  • if ($this->_aParameters['isImage'] && !$this->isImage($aSubmittedFile['tmp_name']))
  • throw new UploadException (UploadHelper::INVALID_IMAGE_FILE);
  • if (!is_dir ($this->_aParameters['destinationFolder']) && $this->_aParameters['createSubFolders'])
  • $this->createSubFolders ();
  • if (!is_dir ($this->_aParameters['destinationFolder']) && !$this->_aParameters['createSubFolders'])
  • throw new UploadException (UploadHelper::INEXISTANT_DESTINATION);
  • $sFileName = (isset ($this->_aParameters['fileName'])) ? $this->_aParameters['fileName'] : $aSubmittedFile['name'];
  • if ($this->_aParameters['cleanFileName'])
  • $sFileName = $this->cleanFileName ($sFileName);
  • $sFilePath = $this->_aParameters['destinationFolder'].$sFileName;
  • if (file_exists ($sFilePath) && !$this->_aParameters['rename'])
  • throw new UploadException (UploadHelper::EXISTANT_FILE);
  • if (file_exists ($sFilePath) && $this->_aParameters['rename'])
  • $sFilePath = $this->renameFile ($sFilePath);
  • if (!move_uploaded_file ($aSubmittedFile['tmp_name'], $sFilePath))
  • throw new UploadException (UploadHelper::UNABLE_TO_MOVE);
  • $this->_aParameters['filePath'] = $sFilePath;
  • return $sFilePath;
  • }
  • }
  • ?>
  • Et l'exemple :
  • <?php
  • if (isset ($_FILES['fichier'])) {
  • require_once ('../Alternativ/Helpers/UploadHelper.php');
  • $oU = new UploadHelper ();
  • // Vous devez spécifier un répertoire de destination !
  • $oU->destinationFolder = "./repertoire/dupload/";
  • // Ensuite vous pouvez spécifier un nom de fichier, s'il n'y en a pas,
  • // ce sera celui fournit par l'utilisateur qui sera pris
  • $oU->fileName = "nomdefichier.extension";
  • // Au lieu d'utiliser la commande $oU->destinationFolder + $oU->fileName
  • // Vous pouvez utiliser celle-ci, strictement identique !
  • $oU->filepath = "./repertoire/dupload/nomdefichier.extension";
  • // Vous pouvez spécifier un tableau d'extensions autorisées
  • $oU->allowedExt = array ('png', 'bmp', 'gif', 'jpg', 'jpeg');
  • // Vous pouvez aussi passer par les fonctions addAllowedExtension en indiquant un tableau d'extensions
  • // ou juste une extension. Dans les deux cas, les valeurs seront ajoutées au tableau en cours
  • // Pour vider le tableau, vous faites $oU->allowedExt = array (); ou vous appelez la méthode
  • $oU->cleanAllowedExtension ();
  • // Si le tableau est vide, toutes les extensions seront autorisées
  • // Si rename est à true, cela permet de renommer le fichier en ajoutant un (x) (ou x = 0 à n)
  • // avec n un nombre tant que le fichier existe, ce qui peux donner fichier.txt, ou s'il existe
  • // fichier(0).txt, ou s'il existe, fichier(1).txt, etc
  • $oU->rename = true;
  • // Valeur par défaut : false;
  • // Si cleanFileName est à true, cela aura pour effet de remplacer tous les caractères autre que
  • // alphanumérique, dot et _ par leur équivalent alphanumérique (é=>e par exemple) ou par un _
  • $oU->cleanFileName = true;
  • // Valeur par défaut : false;
  • // Si le repertoire dans lequel le fichier sera déposé n'exisite pas et que createSubFolders et à true
  • // alors la classe créera tous les dossiers et sous dossiers nécéssaires.
  • $oU->createSubFolders = true;
  • // Valeur par défaut : true;
  • // Limite la taille de chargement, et fait une vérification sur la taille réelle du fichier
  • // (n'interprete pas les valeurs du navigateur (car elles peuvent être faussées))
  • $oU->maxFileSize=512000;
  • // Si ce parametre est à true, va appeler la méthode isImage afin de vérifier l'en tête du fichier pour tester si c'est bien une image !
  • $oU->isImage = true;
  • // On lance l'upload ! :)
  • $oU->upload ($_FILES['fichier']);
  • }
  • else {
  • ?>
  • <form action="index.php" method="post" enctype="multipart/form-data">
  • <p><input type="file" name="fichier" /><input type="submit" value="Envoyer" /></p>
  • </form>
  • <?php
  • }
  • ?>
<?php
/**
 * @name SpecialException
 * @filesource SpecialException.php
 * 
 * @author Cyril Nicodème
 * @license Gnu/Agpl
 * @version 0.1
 * 
 * @since 18/01/2008
 */
class SpecialException extends Exception {
	public function __construct ($iCode, $iParameter = null) {
		// Ici vous pouvez appeler un fichier xml pour aller dans le noeud __lang__>Class>Code
		// Class étant la classe à l'origine de l'erreur
		// Et le code le code retourné par l'erreur
		// Comme cela vous disposez d'une gestion d'erreur multilangue

		// C'est qu'une idée, c'est pour ca que je n'ai mis que des commentaires, que vous adaptiez la classe à vos besoins ! :)
	}
}
?>

<?php
/**
 * @name InvalidParameterException
 * @filesource InvalidParameterException.php
 * 
 * @author Cyril Nicodème
 * @license Gnu/Agpl
 * @version 0.1
 * 
 * @since 18/01/2008
 */
class InvalidParameterException extends SpecialException {
	const BOOLEAN_NEEDED 	= 0;
	const INT_NEEDED 	= 1;
	const STRING_NEEEDED 	= 2;
	const ARRAY_NEEDED 	= 4;
	const RESOURCE_NEEDED 	= 8;
	const OBJECT_NEEDED 	= 16;
	const INVALID_KEY	= 32;
}
?>

<?php
define ('DIR_S', DIRECTORY_SEPARATOR);
/**
 * @name UploadException
 */
class UploadException extends SpecialException {};

/**
 * @name Upload
 * @filesource Upload.php
 * 
 * @author Cyril Nicodème
 * @license Gnu/Agpl
 * @version 0.1
 * 
 * @since 12/01/2008
 */
class UploadHelper {
	/**
	 * @property Constants of designed error
	 */
	const UNAUTHORIZED_FORM_SIZE 	= 1;		// The file size is over the form authorized size
	const UNAUTHORIZED_SIZE 	= 2;		// The file size is over the authorized size
	const UNALLOWED_EXTENSION 	= 3;		// The file does not have an authorized extension
	const ILLEGAL_FILE_NAME 	= 4;		// The file contains Illegal Characters
	
	const INCOMPLETE_FILE 		= 10;		// The file was not completely uploaded
	const UNUPLOADED_FILE 		= 11;		// No file was uploaded
	const INVALID_FILE 		= 12;		// The file is not a valid uploaded file
	const INVALID_IMAGE_FILE 	= 13;		// The file is not a valid Image File
	
	const UNABLE_CREATE_FOLDER 	= 20;		// Unable to create a subfolder
	const INEXISTANT_DESTINATION 	= 21;		// Destination Folder does not exists !
	const EXISTANT_FILE 		= 22;		// The file already exists
	const INEXISTANT_FILE 		= 23;		// The file does not exists
	const UNABLE_TO_MOVE 		= 24;		// Unable to upload the file. Maybe you haven\'t to write into the folder ?
	
	/**
	 * @var Array $_aParameters
	 * Contain all the parameters
	 */
	private $_aParameters = array (
		// @var String : Contain the Path to the destination folder
		'destinationFolder' => '',
	
		// @var String : Contain the name of the file
		'fileName' => '',
	
		// @var String : Contain the destination folder + the file name
		'filePath' => '',
	
		// @var Array : Contain an array of Allowed extensions. If it's an empty array, all the extensions will be allowed
		'allowedExt' => array (),
	
		// @var boolean : Indicate if we rename the file (if already exists) or not
		'rename' => false,
	
		// @var boolean : Indicate if we cleaning the file from strange characters (allow only alphanumeric, ., - and _)
		'cleanFileName' => false,
	
		// @var boolean : Indicate if we create the subfolder for the destinationFolder value
		'createSubFolders' => true,
	
		// @var int : Indicate the max file size for the uploaded file
		'maxFileSize' => 0,
	
		// @var boolean : Indicate if we need to check if the file is an image
		'isImage' => false);
	
	/**
	 * @name __set
	 * Modify the values : destinationFolder, fileName, filePath, allowedExt, rename, cleanFileName, createSubFolders, maxFileSize, isImage
	 * 
	 * @param String $sKey
	 * @param Mixed (String, Array, Boolean) $mValue
	 * 
	 * @return void
	 */
	public function __set ($sKey, $mValue) {
		if (!is_string ($sKey))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		switch (strtolower ($sKey)) {
			case 'destinationfolder':
				if (!is_string ($mValue))
					throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
				
				$mValue = str_replace(array ("\\", "/"), DIR_S, $mValue);
				
				if (substr ($mValue, -1) != DIR_S)
					$mValue .= DIR_S;
				$this->_aParameters['destinationFolder'] = $mValue;
				break;
			case 'filename':
				if (!is_string ($mValue))
					throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
				
				$this->_aParameters['fileName'] = $mValue;
				break;
			case 'filepath':
				if (!is_string ($mValue))
					throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 2);
					
				$mValue = str_replace(array ("\\", "/"), DIR_S, $mValue);
				$this->_aParameters['destinationFolder'] = substr ($mValue, 0, strrpos ($mValue, DIR_S)+1);
				$this->_aParameters['fileName'] = substr ($mValue, strrpos ($mValue, DIR_S)+1);
				$this->_aParameters['filePath'] = $mValue;
				break;
			case 'allowedext':
				if (!is_array ($mValue))
					throw new InvalidParameterException (InvalidParameterException::ARRAY_NEEEDED, 2);
				
				$this->_aParameters['allowedExt'] = $mValue;
				break;
			case 'rename':
				if (!is_bool ($mValue))
					throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
				
				$this->_aParameters['rename'] = $mValue;
				break;
			case 'cleanfilename':
				if (!is_bool ($mValue))
					throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
				
				$this->_aParameters['cleanFileName'] = $mValue;
				break;
			case 'createsubfolders':
				if (!is_bool ($mValue))
					throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
				
				$this->_aParameters['createSubFolders'] = $mValue;
				break;
			case 'maxfilesize':
				if (!is_int ($mValue))
					throw new InvalidParameterException (InvalidParameterException::INT_NEEDED, 2);
				
				$this->_aParameters['maxFileSize'] = $mValue;
				break;
			case 'isimage':
				if (!is_bool ($mValue))
					throw new InvalidParameterException (InvalidParameterException::BOOLEAN_NEEDED, 2);
				
				$this->_aParameters['isImage'] = $mValue;
				break;
			default:
				throw new InvalidParameterException (InvalidParameterException::INVALID_KEY, $sKey);
		}
	}
	
	/**
	 * @name __get
	 * Get the values : destinationFolder, fileName, filePath, allowedExt, rename, cleanFileName, createSubFolders, maxFileSize, isImage
	 * 
	 * @param String $sKey
	 * 
	 * @return Mixed (String, Array, Boolean)
	 */
	public function __get ($sKey) {
		if (!is_string ($sKey))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		if (isset ($this->_aParameters [$sKey]))
			return $this->_aParameters [$sKey];
		else
			throw new InvalidParameterException (InvalidParameterException::INVALID_KEY, $sKey);
	}
	
	/**
	 * @name addAllowedExtension
	 * Add a specific extension or an array of extensions
	 * 
	 * @param Mixed (Array, String) $mValue
	 * 
	 * @return void
	 */
	public function addAllowedExtension ($mValue) {
		if (is_array ($mValue))
			$this->_aParameters['allowedExt'] = array_merge ($this->_aParameters['allowedExt'], $mValue);
			elseif (is_string ($mValue))
		$this->_aParameters['allowedExt'] [] = $mValue;
		else
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED + InvalidParameterException::ARRAY_NEEEDED, 1);
	}
	
	/**
	 * @name cleanAllowedExtension
	 * Set the $_aAllowedExt array empty
	 * 
	 * @return void
	 */
	public function cleanAllowedExtension () {
		$this->_aParameters['allowedExt'] = array ();
	}
	
	/**
	 * @name createSubFolders
	 * Create sub folders from a specific path or from the $_sDestinationFolder
	 * 
	 * @param String $sFolderToCreate (optional)
	 * 
	 * @return void
	 */
	public function createSubFolders  ($sFolderToCreate=null) {
		if (isset ($sFolderToCreate) && !is_string ($sFolderToCreate))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		if (!isset ($sFolderToCreate))
			$sFolderToCreate = $this->_aParameters['destinationFolder'];
		
		$aFolders = explode (DIR_S, $sFolderToCreate);
		$sFinalFolder = '';
		foreach ($aFolders as $sFolder) {
			$sFinalFolder .= $sFolder.DIR_S;
			if (!is_dir ($sFinalFolder)) {
				if (!mkdir ($sFinalFolder))
					throw new UploadException (UploadHelper::UNABLE_CREATE_FOLDER);
			}
		}
	}
	
	/**
	 * @name cleanFileName
	 * Modify the value to be only alphanumeric, _, - and .
	 * 
	 * @param String $sFileName
	 * 
	 * @return String
	 */
	public function cleanFileName ($sFileName) {
		if (!is_string ($sFileName))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		$aSearch = array ('#à|â|ä#i', '#é|è|ê|ë#i', '#î|ï#i', '#ô|ö#i', '#ù|û|ü#i', '#ç#i', '#&#i', '#@#i', "# |'#", '#"#', '#[^a-zA-Z0-9_\.-]*#i');
		$aReplace = array('a', 'e', 'i', 'o', 'u', 'c', '_and_', 'at', '_');
		return preg_replace($aSearch, $aReplace, strtolower($sFileName));
	}
	
	/**
	 * @name renameFile
	 * Rename a specific value while the file from the given file path exists and return the new file path
	 * 
	 * @param String $sFilePath
	 * 
	 * @return String
	 */
	public function renameFile ($sFilePath) {
		if (!is_string ($sFilePath))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		$sFileName = substr ($sFilePath, strrpos ($sFilePath, DIR_S)+1);
		$sDestinationFolder = substr ($sFilePath, 0, strrpos ($sFilePath, DIR_S)+1);
		
		$sBaseName = substr ($sFileName, 0, strrpos ($sFileName, '.'));
		$sExtension = '.'.preg_replace ('`.*\.([^\.]*)$`', '$1', $sFileName);
		
		$sAdd = '';
		$iWhile = 0;
		
		while (file_exists ($sDestinationFolder.$sBaseName.$sAdd.$sExtension)) {
			$sAdd = '('.$iWhile.')';
			$iWhile++;
		}
		
		return $sDestinationFolder.$sBaseName.$sAdd.$sExtension;
	}
	
	/**
	 * @name isImage
	 * Get if the file is an image or not
	 * 
	 * @param String $sFilePath
	 * 
	 * @return Boolean
	 */
	public function isImage ($sFilePath) {
		if (!is_string ($sFilePath))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		if (!file_exists ($sFilePath))
			throw new UploadException (UploadHelper::INEXISTANT_FILE);
		
		$aParams = @getimagesize($sFilePath);
		
		/*
		 * 1  = IMAGETYPE_GIF
		 * 2  = IMAGETYPE_JPEG
		 * 3  = IMAGETYPE_PNG
		 * 4  = IMAGETYPE_SWF
		 * 5  = IMAGETYPE_PSD
		 * 6  = IMAGETYPE_BMP
		 * 7  = IMAGETYPE_TIFF_II (ordre d'octets d'Intel)
		 * 8  = IMAGETYPE_TIFF_MM (ordre d'octets Motorola)
		 * 9  = IMAGETYPE_JPC
		 * 10 = IMAGETYPE_JP2
		 * 11 = IMAGETYPE_JPX
		 * 12 = IMAGETYPE_JB2
		 * 13 = IMAGETYPE_SWC
		 * 14 = IMAGETYPE_IFF
		 * 15 = IMAGETYPE_WBMP
		 * 16 = IMAGETYPE_XBM
		 */
		if (!isset ($aParams[2]))
			return false;
		elseif ($aParams[2] > 0 && $aParams[2] < 16)
			return true;
		else
			return false;
	}
	
	/**
	 * @name upload
	 * Upload the file given into the $_sDestinationFolder given and return the file path
	 * 
	 * @param Array $aSubmittedFile
	 * 
	 * @return String
	 */
	public function upload ($aSubmittedFile) {
		if (!is_array ($aSubmittedFile))
			throw new InvalidParameterException (InvalidParameterException::STRING_NEEEDED, 1);
		
		if ($aSubmittedFile['error'] == UPLOAD_ERR_INI_SIZE)
			throw new UploadException (UploadHelper::UNAUTHORIZED_SIZE);
		
		if ($aSubmittedFile['error'] == UPLOAD_ERR_FORM_SIZE)
			throw new UploadException (UploadHelper::UNAUTHORIZED_FORM_SIZE);
		
		if ($aSubmittedFile['error'] == UPLOAD_ERR_PARTIAL)
			throw new UploadException (UploadHelper::INCOMPLETE_FILE);
		
		if ($aSubmittedFile['error'] == UPLOAD_ERR_NO_FILE)
			throw new UploadException (UploadHelper::UNUPLOADED_FILE);
		
		if (!is_uploaded_file ($aSubmittedFile['tmp_name']))
			throw new UploadException (UploadHelper::INVALID_FILE);
		
		if (isset ($this->_aParameters['maxFileSize']) && filesize ($aSubmittedFile['tmp_name']) > $this->_aParameters['maxFileSize'])
			throw new UploadException (UploadHelper::UNAUTHORIZED_SIZE);
		
		if (preg_match('#[\x00-\x1F\x7F-\x9F/\\\\]#', $aSubmittedFile['name']))
			throw new UploadException (UploadHelper::ILLEGAL_FILE_NAME);
		
		if ((count ($this->_aParameters['allowedExt']) > 0) && 
			!(in_array (preg_replace ('`.*\.([^\.]*)$`', '$1', $aSubmittedFile['name']), $this->_aParameters['allowedExt'])))
			throw new UploadException (UploadHelper::UNALLOWED_EXTENSION);
		
		if ($this->_aParameters['isImage'] && !$this->isImage($aSubmittedFile['tmp_name']))
			throw new UploadException (UploadHelper::INVALID_IMAGE_FILE);
		
		if (!is_dir ($this->_aParameters['destinationFolder']) && $this->_aParameters['createSubFolders'])
			$this->createSubFolders ();
		
		if (!is_dir ($this->_aParameters['destinationFolder']) && !$this->_aParameters['createSubFolders'])
			throw new UploadException (UploadHelper::INEXISTANT_DESTINATION);
		
		$sFileName = (isset ($this->_aParameters['fileName'])) ? $this->_aParameters['fileName'] : $aSubmittedFile['name'];
		
		if ($this->_aParameters['cleanFileName'])
			$sFileName = $this->cleanFileName ($sFileName);
		
		$sFilePath = $this->_aParameters['destinationFolder'].$sFileName;

		if (file_exists ($sFilePath) && !$this->_aParameters['rename'])
			throw new UploadException (UploadHelper::EXISTANT_FILE);
			
		if (file_exists ($sFilePath) && $this->_aParameters['rename'])
			$sFilePath = $this->renameFile ($sFilePath);
		
		if (!move_uploaded_file ($aSubmittedFile['tmp_name'], $sFilePath))
			throw new UploadException (UploadHelper::UNABLE_TO_MOVE);
		
		$this->_aParameters['filePath'] = $sFilePath;
		return $sFilePath;
	}
}
?>


Et l'exemple : 
<?php
if (isset ($_FILES['fichier'])) {
	require_once ('../Alternativ/Helpers/UploadHelper.php');
	$oU = new UploadHelper ();
	
	// Vous devez spécifier un répertoire de destination !
	$oU->destinationFolder = "./repertoire/dupload/";
	
	// Ensuite vous pouvez spécifier un nom de fichier, s'il n'y en a pas,
	// ce sera celui fournit par l'utilisateur qui sera pris
	$oU->fileName = "nomdefichier.extension";
	
	// Au lieu d'utiliser la commande $oU->destinationFolder + $oU->fileName
	// Vous pouvez utiliser celle-ci, strictement identique !
	$oU->filepath = "./repertoire/dupload/nomdefichier.extension";
	
	// Vous pouvez spécifier un tableau d'extensions autorisées
	$oU->allowedExt = array ('png', 'bmp', 'gif', 'jpg', 'jpeg');
	// Vous pouvez aussi passer par les fonctions addAllowedExtension en indiquant un tableau d'extensions 
	// ou juste une extension. Dans les deux cas, les valeurs seront ajoutées au tableau en cours
	// Pour vider le tableau, vous faites $oU->allowedExt = array (); ou vous appelez la méthode
	$oU->cleanAllowedExtension ();
	
	// Si le tableau est vide, toutes les extensions seront autorisées
	
	
	// Si rename est à true, cela permet de renommer le fichier en ajoutant un (x) (ou x = 0 à n)
	// avec n un nombre tant que le fichier existe, ce qui peux donner fichier.txt, ou s'il existe
	// fichier(0).txt, ou s'il existe, fichier(1).txt, etc
	$oU->rename = true;
	// Valeur par défaut : false;
	
	// Si cleanFileName est à true, cela aura pour effet de remplacer tous les caractères autre que 
	// alphanumérique, dot et _ par leur équivalent alphanumérique (é=>e par exemple) ou par un _
	$oU->cleanFileName = true;
	// Valeur par défaut : false;
	
	// Si le repertoire dans lequel le fichier sera déposé n'exisite pas et que createSubFolders et à true
	// alors la classe créera tous les dossiers et sous dossiers nécéssaires.
	$oU->createSubFolders = true;
	// Valeur par défaut : true;
	
	// Limite la taille de chargement, et fait une vérification sur la taille réelle du fichier
	// (n'interprete pas les valeurs du navigateur (car elles peuvent être faussées))
	$oU->maxFileSize=512000;

	// Si ce parametre est à true, va appeler la méthode isImage afin de vérifier l'en tête du fichier pour tester si c'est bien une image !
	$oU->isImage = true;
	
	// On lance l'upload ! :)
	$oU->upload ($_FILES['fichier']);
	
}
else {
?>
<form action="index.php" method="post" enctype="multipart/form-data">
<p><input type="file" name="fichier" /><input type="submit" value="Envoyer" /></p>
</form>
<?php
}
?>

Conclusion

Bon, ce n'est pas quelque chose de très sorcier, mais ca peux toujours servir.

Si toutefois vous avez des remarques, conseils et autre, n'hésitez pas ! :)
18 janvier 2008 19:16:03 :
Ajout du gestionnaire d'Exception, maintenant les exceptions sont gérées par un code. Ajout de la méthode isImage, afin de vérifier l'en-tête de l'image pour augmenter la sécurité ! (par ailleur ajout du parameter isImage en tant que boolean pour appeler ou pas la méthode pendant l'upload)
18 janvier 2008 19:18:21 :
Ajout des classes d'Exceptions (en tant que possibilité !) et passage des erreurs en tant que Code d'erreur. Ajout de la méthode isImage () afin de vérifier si le fichier passé est bien une image. Cette méthode sera appelée pendant l'upload si la variable UploadHelper::isImage est à true (defaut : false);
20 avril 2008 16:00:21 :
Correction de bug
  • signaler à un administrateur
    Commentaire de webdeb le 18/01/2008 09:06:06 8/10

    J'ai parcouru en diagonale le code. C'est propre rien à dire ;)

  • signaler à un administrateur
    Commentaire de codefalse le 18/01/2008 13:03:30 administrateur CS

    Merci c'est gentil :)

  • signaler à un administrateur
    Commentaire de codefalse le 18/01/2008 19:20:16 administrateur CS

    Une petite mise à jour du code afin d'améliorer le script :)
    Vous pensez quoi de la gestion des exceptions par Code (la classe fille de exception (SpecialException, dans l'idée, sera chargé d'aller récuperer le message correspondant à l'erreur dans un fichier xml (ou bdd) pour retourner un message adapté à la langue par exemple)

  • signaler à un administrateur
    Commentaire de malalam le 18/01/2008 20:29:23 administrateur CS 8/10

    Hello,

    c'est pas mal, une idée sympa et mieux codé que la plupart des autres codes du genre.
    Je verrai quand même des choses plus poussées...: manque plus qu'n framework JS pour gérer tes uploads côté client, avec progress bar via ajax etc :-)

  • signaler à un administrateur
    Commentaire de codefalse le 18/01/2008 20:44:07 administrateur CS

    oué mais ca, d'apres moi, c'est plus à la partie vue de s'en occuper (js et ajax) et dans mon cas (pour le moment) je travail que coté Controller et bientot je passe au model :p
    Mais oué ca pourrait être un plus ! :)

  • signaler à un administrateur
    Commentaire de DiGhan le 20/01/2008 14:46:56

    Je trouve qu'à l'utilisation cette classe n'est pas très intuitive. Ecrire une 10aine de lignes pour setter les options d'upload, je trouve ça relativement embetant (gros faineant que je suis).

    J'aurai plutôt vu le setup des principales infos (chemin de destination, rename, etc) directement dans le constructeur.

  • signaler à un administrateur
    Commentaire de codefalse le 21/01/2008 00:08:36 administrateur CS

    mais justement le probleme est là, toi tu veux parametrer juste deux trois éléments (destination, renommage et vérification de l'image par exemple), mais un autre voudra plus de possibilités, c'est pour ca !

    Apres rien ne t'empeche de modifier ta classe pour que les parametres que tu met tout le temps à true, à x ou a "qqchose", tu le fait dans la classe dans les défaut, comme ca tu les ignores par la suite :)

  • signaler à un administrateur
    Commentaire de cwi le 21/02/2008 11:36:52

    Cette class semble impeccable :)

    Par contre est il possible de récupérer les informations : chemin de répertoire, nom du fichier, extension du fichier, taille... ?

  • signaler à un administrateur
    Commentaire de codefalse le 21/02/2008 16:49:06 administrateur CS

    C'est vrai qu'en l'état actuel, cette classe ne permet pas de récuperer les informations excepté le chemin du repertoire, le nom du fichier (un $instance->filePath, fileName, destinationFolder devraient fonctionner).
    Mais pour connaitre le type de fichier, la taille, et les informations de ce type là, en effet il n'y a aucune possibilité pour le moment, je vais regarder ca de plus pres ! :)

  • signaler à un administrateur
    Commentaire de gentelmanmd le 26/02/2008 03:14:04

    merci bcp

  • signaler à un administrateur
    Commentaire de codefalse le 26/02/2008 12:14:31 administrateur CS

    Mais de rien ! :)
    Content que ca te plaise ! :)

  • signaler à un administrateur
    Commentaire de flieutaud le 19/04/2008 21:08:16

    Bonjour,

    J'essaye cette classe et je suis confronté à ce message d'erreur (dès que je mets une image dépassant la limite autorisée) :
    Warning: Missing argument 2 for SpecialException::__construct(), called in /home/fred/demapage/classes/upload.class.php on line 382 and defined in /home/fred/demapage/classes/upload.class.php on line 13

    Fatal error: Uncaught exception 'UploadException' in /home/fred/demapage/classes/upload.class.php:382 Stack trace: #0 /home/fred/demapage/image_upload.php(53): UploadHelper->upload(Array) #1 {main} thrown in /home/fred/demapage/classes/upload.class.php on line 382

    J'avoue n'être que débutant, mais très désireux d'apprendre et de progresser... Si quelqu'un peut m'aiguiller, ce serait sympathique.
    Merci !

    Fred.

  • signaler à un administrateur
    Commentaire de codefalse le 20/04/2008 15:59:32 administrateur CS

    En fait c'est une erreur dans le code, en effet.
    Dans cette ligne :
    # class SpecialException extends Exception {
    # public function __construct ($iCode, $iParameter) {

    Remplace $iParameter par $iParameter = null et ca marchera :)
    (le code est corrigé en conséquence

  • signaler à un administrateur
    Commentaire de flieutaud le 20/04/2008 18:06:55

    Bonjour et merci pour l'aide. La première ligne d'erreur a en effet disparu suite à la midfication proposée, mais il reste encore la seconde si j'essaye d'uploader une image trop volumineuse...

  • signaler à un administrateur
    Commentaire de codefalse le 20/04/2008 18:14:16 administrateur CS

    l'erreur est normale.
    Avant l'upload du fichier, le script va effectuer divers tests (est-ce que le fichier à bien été uploadé, est-ce que le repertoire de destination existe, les droits sont-ils corrects, etc).
    Dans ton cas, il y a eu une erreur durant l'upload car le fichier est trop volumineux, donc l'erreur (cela s'appelle une exception) est lancée.

    Pour éviter l'erreur, il suffit de mettre un bloc try/catch de cette facon :
    // On reprends tout le code d'avant et on modifie la derniere ligne par :

    try {
         $oU->upload ($_FILES['fichier']);
    }
    catch (SpecialException $oSE) {
        echo "Une erreur s'est produite durant l'upload, le fichier n'à put être uploadé.\n<br />";
        echo "La raison était : ".$oSE->getMessage ();
    }

    et voila ! :)

  • signaler à un administrateur
    Commentaire de flieutaud le 21/04/2008 01:01:30

    Merci encore pour la réponse. Je m'attendais juste à avoir un message d'erreur plus clair, comme indiqué dans le commentaire ci-dessus ;-)
    Je pensais (à tort) que les exceptions permettaient justement d'indiquer plus clairement les erreurs et j'imaginais donc que la classe proposées utilisait un tel système. En parcourant le code, je vois que l'on peut pointer vers un fichier xml qui indiquerait tout ça (et même en plusieurs langues). Bon, pour le moment, c'est au dessus de mes moyens... Je vais voir de plus près l'utilisation du bloc try/catch.

    Merci encore pour ces indications riches en enseignement.

  • signaler à un administrateur
    Commentaire de codefalse le 21/04/2008 01:16:20 administrateur CS

    mais de rien :)

  • signaler à un administrateur
    Commentaire de romainlatin le 21/04/2008 12:24:36

    salut tres bon code! j'ai une question a propos de renameFile j'ai testé la fonction et l'extension n'ai jamais rajouté au fichier uploadé?
    (0) au lieu de (0).txt

    merki

  • signaler à un administrateur
    Commentaire de DrAgOnLORdS le 26/06/2008 12:20:16

    Salut Codefalse,

    J'ai une question mais rien à voir avec la classe en elle même.
    Vu la façon de commenter tu utilises un système de documentation automatique ? Ce que je voulais savoir, c'est quel système utilises tu ?
    phpDocumentor ?

    merci d'avance.

  • signaler à un administrateur
    Commentaire de codefalse le 26/06/2008 13:03:46 administrateur CS

    En fait je commente plus ou moin dans le style de la javadoc. Je n'utilise pas de systeme de documentation automatique mais le fait de se baser sur un style javadoc me permet d'utiliser de nombreux systemes compatibles javadoc (genre Doxygen ou probablement PhpDocumentor)
    C'est le style de commentaire que tu trouvera le plus souvent. Apres d'autres font differement, c'est sur :)

Ajouter un commentaire

Discussions en rapport avec ce code source

Pub



Appels d'offres

Dessins techniques
Budget : 60€
Animation Flash - Doma...
Budget : 370€
Application flash medi...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique