Errores en PHP “Dar cera pulir cera”

Una de las cosas que más tiempo lleva cuando tienes todo funcionando es detectar los posibles errores y encontrar qué hacer con ellos. No está mal que ocurran errores, eso es lo normal … lo que está mal es que no sean detectados.

Estoy haciendo una aplicación web que consiste básicamente en subir archivos para poder transformarlos en otra cosa (imágenes en PDF, archivos de Word en PDF, PDFs en PDFs impuestos) . En estos momentos estoy luchando con el sistema para subir archivos y como decía al inicio lo que más tiempo lleva es pulir los errores, detectarlos y decidir que hacer con ellos … y si el archivo que se sube es de un formato no soportado?, y si es una archivo demasiado grande?, y si … ?

Un formulario envía los datos de los archivos elegidos a un script PHP que los procesa y si todo va bien los muestra en pantalla junto a las opciones de conversión.

<form id="upload" action="upload.php" method="post" enctype="multipart/form-data">
<input id="file" type="file" name="file[]" />
<input type="submit" name="enviar" value="SUBIR" />
</form>

Este script PHP es el que se encarga de comprobar que todo va bien, comprueba que realmente le llegan datos, y que son del formato adecuado, en el ejemplo estoy comprobando estas cosas y muchas más … no más fallos por favor !!

// compruebo que llegan los datos
if(!$_POST){
 echo "<div class='un_archivo error'>";
 echo "ERROR no hay datos POST";
 echo "</div>";
 exit;
}
// compruebo que dentro de los datos hay archivos
if(!$_FILES){
 echo "<div class='un_archivo error'>";
 echo "ERROR no hay datos FILES";
 echo "</div>";
 exit;
}
// cuantos archivos ??
$cuantos = count($_FILES['file']['name']);
for ($i=0;$i<$cuantos;$i++) {

 // si el archivo trae un error, lo muestro
 $error = $_FILES['file']['error'][$i];
 $upload_errors = array(
 UPLOAD_ERR_OK => "No errors.",
 UPLOAD_ERR_INI_SIZE => "Larger than upload_max_filesize.",
 UPLOAD_ERR_FORM_SIZE => "Larger than form MAX_FILE_SIZE.",
 UPLOAD_ERR_PARTIAL => "Partial upload.",
 UPLOAD_ERR_NO_FILE => "No file.",
 UPLOAD_ERR_NO_TMP_DIR => "No temporary directory.",
 UPLOAD_ERR_CANT_WRITE => "Can't write to disk.",
 UPLOAD_ERR_EXTENSION => "File upload stopped by extension.",
 'UPLOAD_ERR_EMPTY' => "File is empty." // add this to avoid an offset
 );
 if ($error > 0){
 echo "<div class='un_archivo error'>";
 echo "Error $upload_errors[$error]";
 echo "</div>";
 exit;
 }

 // si el archivo es demasiado grande, ERROR
 $maxsize = 2000; // en KBs
 $size_bytes = filesize($_FILES['file']['tmp_name'][$i]);
 if ($size_bytes) {
 $size = $size_bytes / 1024;
 }
 else {
 echo "<div class='un_archivo error'>";
 echo "no puedo leer el tamaño en KBs de la imagen";
 echo "</div>";
 exit;
 }

 // Si el tipo de archivo está vacio no puedo continuar, ERROR
 // tipo de archivo segun el BROWSER
 #$tipo = $_FILES['file']['type'][$i];
 // tipo de archivo según el SERVER
 $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
 $filename = $_FILES['file']['tmp_name'][$i];
 $tipo = finfo_file($finfo, $filename);
 finfo_close($finfo);

 if ($tipo == ""){
 echo "<div class='un_archivo error'>";
 echo "no reconozco el formato de imagen $tipo";
 echo "</div>";
 exit;
 }

 // Si el tipo de archivo es uno de los soprtados, CONTINUO
 if ( (($tipo == "application/pdf") || ($tipo == "image/jpeg") || ($tipo == "image/jpg") || ($tipo == "image/png")|| ($tipo == "image/tiff")) && ( $size < $maxsize)) {

 // directorio donde se copian los archivos, compruebo que existe y que tiene permisos de escritura
 $dir_up = "uploaded/";
 if (file_exists($dir_up) && is_writable($dir_up)) {
 // haz algo aqui
 }
 else {
 echo "<div class='un_archivo error'>";
 echo 'El directorio elegido no existe o no puedo escribir en él';
 echo "</div>";
 exit;
 }

// copio el archivo e la ubicacion elegida
 $original = $_FILES['file']['tmp_name'][$i];
 $file_new = $dir_up . $_FILES['file']['name'][$i];
 $move = move_uploaded_file($original,$file_new);

 if (!$move){ echo "<h2>error al mover $original</h2>"; exit; };
 #echo "<div>". $file_new."</div>";

 // y muestro el resultado
 echo "<div class='un_archivo'>";
 echo "<div><a href='".$file_new."' target='blank'>ver archivo</a></div>";

 // si el archivo es un PDF, convierto la primera página en PNG para mostrarla como miniatura
 if ($tipo == "application/pdf"){
 //$thumb = "uploaded/".basename($file_new)."_th.png";
 $thumb = "uploaded/preview2.png";
 $query = "/usr/local/bin/gs-noX11 -sDEVICE=png48 -dFirstPage=1 -dLastPage=1 -dBATCH -dNOPAUSE -dNOOUTERSAVE -sOutputFile='".$thumb."' '".$file_new."'";
 $clean_query = escapeshellcmd($query);
 $result = exec($clean_query);

 echo "<img class='preview' src='".$thumb."' width='90px'>";
 // PRINT
 // cuando esto funciona en local puedo mandar imprimir a una de mis impresoras
 echo "<form id='print' action='print.php' method='post'>";
 echo "<input type='hidden' name='file' value='".$file_new."' size=60> <br>";
 echo "<input type='hidden' name='filetype' value='".$tipo."' size=60>";
 echo "<input type='submit' value='PRINT' >";
 echo "</div>";

 }
 // si el archivo es una imagen, saco su información
 else {
 echo "<img class='preview' src='".$file_new."' width='90px'>";
 // PHP tiene que tener el modulo GD instalado
 $info = getimagesize($file_new);
 $width = $info[0];
 $height = $info[1];
 // ROTAR IMAGENES; todas serán VERTICALES
 if ($width > $height){
 $source = imagecreatefromjpeg($file_new);
 $rotate = imagerotate($source, 270, 0);
 // Output
 $rotando = imagejpeg($rotate,$file_new);
 // ACTUALIZO DATOS
 $info = getimagesize($file_new);
 $width = $info[0];
 $height = $info[1];
 }

// los archivos que subo juntos los separo en PHP
 $imgs['files']=array('name'=>$file_new,'tipo'=>$tipo,'width'=>$width,'height'=>$height);
 if ($files_string==""){ // la primera vez no quiero separador al principio
 $files_string = $file_new."++".$tipo."++".$width."++".$height;
 }
 else {
 $files_string = $files_string."**".$file_new."++".$tipo."++".$width."++".$height;
 }
 }
 echo "</div>"; // termina un_archivo

} // termina IF tipo es valido
 else {
 echo "<div class='un_archivo error'>";
 echo "Error, formato de archivo no soportado $tipo";
 echo "</div>";
 }

?>