Jump to content


Photo

Troca De Idéia - Classe Para Upload


  • Faça o login para participar
1 reply to this topic

#1 Nicholas Pufal

Nicholas Pufal

    Impossível: só existe até alguém duvidar e provar o contrário.

  • Usuários
  • 1655 posts
  • Sexo:Masculino
  • Localidade:Porto Alegre

Posted 21/09/2009, 14:32

Pessoal,

tô fora do circuito há algum tempo, e só agora tô pegando pesado no assunto POO.

Estive vendo diversas classes de resize (c/ métodos para thumb, resize da original, crop e afins...) e reparei que todas "pecam" em ter que introduzir uma boa porção de códigos para suportar múltiplos uploads. Decidi começar o desenvolvimento de uma classe mais eficaz neste ponto, visto quase sempre o upload ser múltiplo.

Não tenho nenhum super poder em POO, e já esbarrei em um complicador que é ter que fazer um laço em cada método, para que ele seja aplicado a cada item do vetor $_FILES.

Alguém já tentou fazer uma implementação neste sentido?

A idéia (para upload já está funcionando) é aplicar a classe de forma bem simples, assim:

if (isset($_POST['submited']))
{

  $file = new UploadPictures($_FILES['pictures']);
  $file->moveFiles();
  echo $file->getErrors();
  
}

A idéia de pegar e transformar o vetor $_FILES em outro, foi do Paulo André (ou Paulo Ricardo, não lembro ao certo). Eu apenas adaptei o raciocínio um pouco pq tinha um pequeno bug (os arquivos tinham que ser enviados em ordem correta).

A classe é esta: (apenas o construtor e os métodos moveFile() e getErrors() que estão funcionando no momento)

<?php

/*
* @author Nicholas Pufal
*/

class UploadPictures 
{
  private $security = array('allowed_types' => array('jpg','gif','png'));
  private $files = array();
  private $errors = array(); 

  private $dest_upload_dir; 
  private $dest_path; 
  
  public function __construct($spfiles, $dest_upload_dir = 'uploads/', $dest_extension = 'jpg')
  {
	$total_files = count($spfiles['name']); 
	$counter = 0;
	
	for ($i=0;$i<$total_files;$i++)
	{
	  if (!empty($spfiles['name'][$i]))
	  {
		$this->files[$counter]['name'] = $spfiles['name'][$i];
		$this->files[$counter]['extension'] = strtolower(pathinfo($spfiles['name'][$i],PATHINFO_EXTENSION));
		$this->files[$counter]['tmp_name'] = $spfiles['tmp_name'][$i];
		$this->files[$counter]['new_name'] = $this->getNewName(). '.' . $dest_extension;
		list($this->files[$counter]['width'],$this->files[$counter]['height']) = getimagesize($spfiles['tmp_name'][$i]);
		$this->files[$counter]['size'] = $spfiles['size'][$i] / 1048576; //convert to megabytes
		
		//$this->files[$counter]['type'] = $spfiles['type'][$i];
		//$this->files[$counter]['error'] = $spfiles['error'][$i];
		
		$counter++;
	  } 
	}
	
	//$this->debugger($this->files);
	$this->dest_upload_dir = $dest_upload_dir;
  }
  
  private function getNewName()
  {
	return md5(time() * mt_rand(1,9));
  }

  /*
  * Salva a imagem enviada (sem alterações), caso ela esteja de acordo com as extensões suportadas.
  * @return bool
  */  
  public function moveFiles()
  {
	foreach($this->files as $k => $v)
	{
	  if ($this->securityCheck($v['extension'],$v['size'],$v['name'],$k))
	  {
		if (move_uploaded_file($v['tmp_name'],$this->dest_upload_dir.$v['new_name']))
		{
		  echo $v['name']. "-> o upload foi concluído com êxito!<br/>";
		}
	  }
	}
  }
  
  private function createResource($ext)
  {
	switch ($ext)
	{
	  case "jpg" :
		return imagecreatefromjpeg($this->dest_path);
		break;
	  case "jpeg" :
		return imagecreatefromjpeg($this->dest_path);
		break;
	  case "png" :
		return imagecreatefrompng($this->dest_path);
		break;
	  case "gif" :
		return imagecreatefromgif($this->dest_path);
		break;
	  default:
		$this->errors[] = "Não foi possível criar um resource para a imagem.";
		break;
	}	
  }
  
  public function createThumb($dest_width = 500, $dest_height = 350, $quality = 80)
  {
	if (file_exists($this->dest_path))
	{
	  $dst_image = imagecreatetruecolor($dest_width, $dest_height);
	  
	  $src_resource = $this->createResource($this->src_extension);
	  
	  imagecopyresampled ($dst_image , $src_resource, 0, 0, 0, 0, $dest_width, $dest_height, $this->src_width, $this->src_height);
	  
	  imagejpeg($dst_image,$this->dest_upload_dir.'thumb_'.$this->getNewName(). $this->dest_extension/*alterar*/, $quality);	  
	}
  }

  private function securityCheck($extension,$size,$name,$k)
  {
	$arr_keys = array_keys($this->security);
	
	//Supported extensions
	if (in_array('allowed_types',$arr_keys))
	{
	  if (!in_array($extension,$this->security['allowed_types']))
	  {
		$this->errors[$k][] = $name ." -> Extensão ".$extension." não é permitida.";
	  }
	}
	
	//Max size
	if (in_array('max_size',$arr_keys))
	{
	  if ($this->security['max_size'] < $size)
	  {
		$this->errors[$k][] = $name ."-> O arquivo ultrapassa o tamanho limite de ".$size;
	  }
	}	
	
	return (empty($this->errors[$k])) ? true : false;
  }
  
  /*
  * Getters and other non-essential methods
  */
  
  private function debugger($f)
  {
	echo "<pre>";
	var_dump($f);
	echo "</pre>";
  }
  
  public function getErrors()
  {
	if (!empty($this->errors))
	{
	  $error = '';
	  
	  foreach($this->errors as $er)
	  {
		foreach($er as $v)
		{
		  $error .= $v."<br/>";
		}
	  }
	  
	  return $error;
	}	
  }
}
?>

(y)
BLOG Touché Criação - Vamos trocar idéias? -> http://blog.touchecriacao.com.br/
// Links úteis: Busca || Regras
// Não respondo dúvidas via mensagem privada. Use o fórum para buscar ou perguntar.

#2 Maykel Esser

Maykel Esser

    Super Veterano

  • Usuários
  • 1536 posts
  • Sexo:Masculino
  • Localidade:Curitiba - PR

Posted 21/09/2009, 15:23

Esses dias eu me quebrei um monte pra criar uma função para upload que pudesse ser chamada através de uma linha apenas, sendo então POO... mas não para uploads múltiplos... ou até dava, mas no meu caso, utilizei apenas o upload. O resize era feito por outro arquivo (já que não domino nada de bibliotecas GD)... o que a minha fazia era:

1. verificar a extensão
2. se passasse, ver o mime-type para evitar os bobinhos que renomeam arquivos exe para jpg para executar em server-side...
3. se passar, verifica o nome, retira espaços, deixa tudo em minusculo, e insere a data e hora completa (sem barras) para não haver perigo de sobreposição...
4. verificava se o diretório escolhido era válido
5. upload

E não ficou grande não! Ficou bem útil... botei até um esqueminha para ver se o usuário postasse um arquivo alterado, caso não, era só passar um parâmetro a mais ($arquivoAntigo)...

Se este post lhe ajudou, ajude o fórum também. Use a reputação de mensagens! add.png





0 user(s) are reading this topic

0 membro(s), 0 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq