• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Battousai

[PHP] Classe de Upload

3 mensagens neste tópico

Bem fiz esta classe para ajudar em algumas coisas típicas quando se trata de uploads. Tinha outras ideias para implementar, mas ainda não tive muitas coisas que me faltassem que me fizessem fazer um update à classe.

Esta classe permite:

  • Definir limites mínimos e máximos de tamanhos de ficheiro. Podem definir o tamanho por Bytes, KBs, MBs e GBs
  • Sacar o tamanho do ficheiro, também em Bytes, KB, MB e GB, facilmente podem adicionar mais.
  • Definir as extensões e Mimes aceites
  • Guardar o ficheiro facilmente.
  • Se necessário, trata do nome do ficheiro e elimina caracteres especiais.
  • Mantém uma contagem do número de ficheiros(objectos) criados.

class Upload {

public
	$name,
	$srcName,
	$size,
	$type,
	$extension;

private
	$_finalStats = array(
		'name' => null,
		'path' => null
	),
	$_rules = array(
		'file_types' => null,
		'extensions' => array(),
		'types' => array(),
		'size' => null
	);

private static
	$countFiles = 0;

const
	FOLDER_PERMISSIONS = 0755,
	ROUNDING_PRECISION = 2;

public function __construct( array & $file, array & $rules = null ){

	self::$countFiles++;

	$this->name = $file['name'];
	$this->srcName = $file['tmp_name'];
	$this->size = $file['size'];
	$this->type = $file['type'];
	$this->extension = $this->getExtension();

	if( $rules )
		$this->setRules( $rules );

}

public function __destruct(){

	if( file_exists( $this->srcName ) )
		unlink( $this->srcName );
	self::$countFiles--;

}

public function set( $name, $value ){

	$this->_finalStats[$name] = $value;

}

public function get( $name ){

	return $this->_finalStats[$name];

}

public static function countFiles(){

	return self::$countFiles;

}

public function getSize( $measure = null ){

	$size = $measure ?
		round( $this->size / $this->getPower( $measure ), self::ROUNDING_PRECISION ) :
		$this->size;

	return $size;

}

/*
	Returns:
	1: if couldn't create directory
	2: if couldn't rename the file to it's final path	
*/
public function SaveIn( $path, $name = null ){

	$fname = $this->_finalStats['name'];
	$name = ( $name ? $name : ( $fname ? $fname : $this->name ) );

	$finalPath = ( substr( $path, -1 ) == '/' ? $path : $path . '/' ) . $name;

	if( ! file_exists( $path ) )
		if( ! mkdir( $path ) )
			return 1;

	chmod( $path, self::FOLDER_PERMISSIONS );

	if( ! move_uploaded_file( $this->srcName, $finalPath ) )
		return 2;

	$this->_finalStats['path'] = $finalPath;

	if( $fname != $name )
		$this->_finalStats['name'] = $name;

	return true;

}

/*
	Rules must be of the correct type for compatibility purposes 
*/
public function setRules( array & $rules ){

	foreach( $rules as $name => $value )
		switch ( $name ){

			case 'types':
				$this->_rules['types'] = (array) $value;
			break;

			case 'extensions':
				$this->_rules['extensions'] = (array) $value;
			break;

			case 'size':
				$this->_rules['size'] = (array) $value;
			break;

		}

}

/*
	Returns:
	1: extensions rule
	2: types rule
	3: size too small
	4: size too big
	5: max and min have the same value
*/
public function breaksRules(){

	foreach( $this->_rules as $name => $value )

		switch( $name ){

			case 'extensions':

				if( ! in_array( $this->extension, $this->_rules['extensions'] ) )
					return 1;

			break;

			case 'types':

				if( ! in_array( $this->type, $this->_rules['types'] ) )
					return 2;

			break;

			case 'size':

				$maxSize = $this->_rules['size']['max'];
				$minSize = $this->_rules['size']['min'];

				if( $maxSize == $minSize )
					return 5;

				$measure = $this->_rules['size']['measure'];

				$size = $measure ?
				round( $this->size / $this->getPower( $measure ), self::ROUNDING_PRECISION ) :
				$this->size;

				if( ( $minSize > 0 ) && ( $size < $minSize ) )
						return 3;
				if( ( $maxSize > 0 ) && ( $size > $maxSize ) )
						return 4;

			break;

		}

	return false;

}

public function sanitizeName(){

	$bad = array( 'Š','Ž','š','ž','Ÿ','À','Á','Â','Ã','Ä','Å','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ñ',
	'Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý','à','á','â','ã','ä','å','ç','è','é','ê',
	'ë','ì','í','î','ï','ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','ÿ',
	'Þ','þ','Ð','ð','ß','Œ','œ','Æ','æ','µ',
	'”',"'",'“','”',"\n","\r",'_');

	$good = array( 'S','Z','s','z','Y','A','A','A','A','A','A','C','E','E','E','E','I','I','I','I','N',
	'O','O','O','O','O','O','U','U','U','U','Y','a','a','a','a','a','a','c','e','e','e',
	'e','i','i','i','i','n','o','o','o','o','o','o','u','u','u','u','y','y',
	'TH','th','DH','dh','ss','OE','oe','AE','ae','u',
	'','','','','','','-');

	$slug = str_replace( $bad, $good, $this->name );

	$slug = trim($slug);

	$bad = array('/\s+/','/[^A-Za-z0-9\-\.]/');
	$good = array('-','');

	$slug = preg_replace($bad, $good, $slug);

	$this->_finalStats['name'] = $slug;

}

private function getPower( $measure ){

	switch( strtoupper( $measure ) ){
		case 'KB':
			$power = 1024;
		break;
		case 'MB':
			$power = pow( 1024, 2 );
		break;
		case 'GB':
			$power = pow( 1024, 3 );
		break;
	}

	return $power;

}

private function getExtension (){

	$ext = explode( '.', $this->name );
	$count = count( $ext ) - 1;
 	$ext = $count ? strtolower( $ext[ $count ] ) : false;

	return $ext;

}

}

Modo de uso ( escrevi aqui directamente, é capaz de ter erros :) )


// Podem definir regras:
$rules = array(
	'size' => array(
		'min' => 3,
		'max' => 9,
		'measure' => 'KB'
	),
	'extensions' => array( 'jpg','jpeg' ),
	'types' => array( 'image/pjpeg', 'image/jpeg' )
);

// Então criam o vosso objecto e passam logo as regras com ele. Podem também adicionar ou mudar as regras com o método setRules()
$upload = new Upload( $_FILES['ficheiro'], $rules );

// Se definiram regras para o upload, podem então ver se o ficheiro quebra alguma.
if( ! $upload->breaksRules() ){ // se quiserem saber o erro em questão, podem ver em comentário a referência para cada erro.

// Se passou, queremos tirar todo os caracteres especiais e espaços.
$upload->sanitizeName();

// Queremos sacar o tamanho em KBs para meter na DB
$tamanho = $upload->getSize('kb'); // tanto faz em maiusculas ou minusculas

// E por fim, queremos guardar o ficheiro.
// Este método vai buscar o nome sem caracteres se chamaram o método sanitizeName(), senão fica o nome original. Podem também introduzir um nome que queiram no segundo argumento.
$upload->saveIn('pasta'); 

}else{
// Se o ficheiro quebrar regras, podem fazer unset, que chama o destruct, que por sua vez vai eliminar o ficheiro.
unset( $upload );
}

Sugestões, críticas e possíveis erros ( não foi intensivamente testado ) bem vindos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora