Bienvenidos a este pequeño y sencillísimo tutorial acerca de cómo podemos crear nuestro propio sistema para subir archivos a nuestro servidor al más puro estilo imageshack o cualquier otro gestor de fotos.
Lo primero, para poder entender perfectamente este tutorial, necesitarás nocioes básicas de php orientado a trabajar con archivos y directorios. Tras eso, podrás entenderlo sin problema alguno.
Empezaré diciendo que el script que usaremos a medida que avance el tutorial podrá ser de gran utilidad a la hora de gestionar los archivos personales de uno, aparte que aquel usuario que no sepa nada de PHP podrá usarlo igualmente, puesto que la configuración es muy sencilla. Bueno, ¡empecemos!
Creemos un archivo con la extensión .php para trabajar dentro de él, podemos usar un editor como el notepad, u otros programas de gestión para páginas web (no recomiendo el frontpage de micro$oft). Una vez estemos dentro iniciamos el código php. Por si acaso no recuerdas los comentários que voy haciendo a lo largo del tutorial, dejo adjuntados unos al código ;-)
mcUploader.php
Codigo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<?php
ob_start();
#######################################
## MC Uploader por Bline para Mctekk
#######################################
#####
## Modifica las siguientes variables
#####
$valext = array('jpg','bmp','gif','png','rar','zip'); # Sigue el patrón para declarar más extensiones válidas #
$dname = ''; # Nombre de la carpeta que contendrá las imágenes #
$durl = ''; # Dirección completa donde esta contenida la carpeta $dname # (SIN LA BARRA FINAL => '/') #
$fsize = '512000'; # Tamaño máximo por cada imagen subida (en bytes), en este caso 500kb #
$ftime = '60'; # Tiempo en minutos del tiempo entre subida y subida de archivo #
$cname = 'mctekkuploadfile'; # Nombre de la cookie que se generará para una mínima protección de flood #
?>
|
En este primer paso, declaro las variables que usaré a lo largo del tutorial y que al usar deberás modificar como bien quieras, esta es la parte, que si no sabes php
solo has de tocar, ya que podrías modificar algo
en el código principal y posiblemente dejar algun bug que alguien pueda explotar ;-), por ahora nada importante, modifica las variables a tu gusto y como mejor convenga, siempre siguiendo el patrón que sigo yo al escribirlas.
En este siguiente paso hay un pequeño mensaje por si te olvidas de que a partir de ahí ya no se modifica :P
Codigo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
<?php
#####
## No modifiques a partir de aquí si no sabes lo que haces, avisad@ quedas ;-)
#####
# Comprobamos si existe el directorio $dname, en caso de negativa, devuelve error y deja de ejecutar el código #
if(!is_dir($dname)){
@mkdir($dname,0600) or die("
<div align=\"center\">
<table border=\"0\" width=\"336\"><tr><td width=\"330\" bgcolor=\"#DDF1F4\" style=\"border: 1px solid #000000; padding: 10px\">
<p align=\"center\"><font face=\"Verdana\"><span style=\"font-size: 9px\">Debe
crear el directorio <b>$dname</b> manualmente, ya que no se ha podido generar
automáticamente.</span></font></td></tr></table></div>"); }
?>
|
Lo que hemos hecho, ha sido si existe mediante la funcion 'is_dir' algun directorio con el nombre que hayas puesto a la variable $dname, de lo contrario, lo crea si tiene permisos, si no salta un mensaje de error y deberás crearlo manualmente usando un gestor FTP.
Ahora veremos si el formulario de envio de archivos, contiene o no información:
Codigo:
1 2 3 4 5
|
<?php
# Comprobamos si el formulario contiene o no información, en caso de afirmación se procesa el formulario comprobando si ya existe un fichero con ese nombre #
if(empty($_POST) or empty($_FILES['file']['name'])){
?>
|
¿Por qué cerramos la etiqueta "?>" de php? Facil, para evitarnos el estar cambiando de html a php, cerramos la etiqueta y dejamos el código html justo debajo de lo que se ha puesto, asi el navegador interpretará que es lo que sucede tras ese código.
Ahora vamos a trabajar con unas tablas en html antes de introducirnos otra vez con el php ^__^
Code:
<!-- Código html que contiene el formulario para subir un archivo --> <table width="400" border="0" align="center"> <tr> <td width="341" bgcolor="#DDF1F4" style="border: 1px solid #000000; padding: 10px"> <form method="POST" enctype="multipart/form-data" action=""> <p align="center"><b> <font face="Verdana" style="font-size: 9px">Subir archivo</font></b><br> <input type='hidden' name='max_file_size' value='<?php echo $fsize; ?>'> <input type="file" name="file" size="20" style="font-family: Verdana; font-size: 9px; color: #000000; border: 1px solid #000000; padding-left: 2px; padding-right: 2px; padding-top: 1px; padding-bottom: 1px"><input type="submit" value="Enviar" name="B1" style="font-family: Verdana; font-size: 9px; color: #000000; border: 1px solid #000000"></p> </form></td></tr></table> <!-- Fin del código html --> |
Esta es la tabla principal del script, donde seleccionas el arquivo que subirás junto al boton enviar y demás.
Ahora abrimos otra pequeñísima etiqueta php, que contendrá el comienzo de la tabla donde se mostrarán los resultados
Codigo:
1 2 3 4 5
|
<?php
# Si contiene información, empezará el proceso de subida #
}else{
?>
|
Ahora abrimos nuevamente html para introducir el principio de la tabla.
Code:
<!-- Abrimos la tabla donde mostraremos el resultado --> <div align=\"center\"> <table width="400" border="0" align="center"> <tr><td width="330" bgcolor="#DDF1F4" style="border: 1px solid #000000; padding: 10px"> <p align="left"><font face="Verdana"><span style="font-size: 9px"> <!-- Continuamos con el código php --> |
Ya hasta el final, no usaremos mas el html, ahora empezaremos el verdadero contenido del php, ahora verificamos si el usuario ha subido algún archivo en los ultimos X minutos, donde X es el tiempo que hayas definido en la variable ftime. También declaramos la variable $ext, que contendrá la extensión del archivo que subamos.
Codigo:
1 2 3 4 5 6 7 8
|
<?php
# Vemos si ha realizado una subida de algún archivo en los $ftime minutos anteriores #
if(!isset($_COOKIE[$cname])){
# Declaramos la variable que guardará la extensión del archivo y comprobamos si es válida
$ext = substr($_FILES['file']['name'],-3);
?>
|
Ahora bien, ¿Qué pasa si la extension es un exe, un archivo php? Que podrian hacernos mucho daño, asi que limitamos las extensiones con el array de arriba.
Codigo:
1 2 3 4 5
|
<?php
# Comprobamos la extensión del archivo para excluir posibles ataques
if(!is_numeric(array_search($ext,$valext))){ echo '<b>Sólo</b> las siguientes extensiones son válidas:<br> ';
while($value = each($valext)){ print '<b>.'.$value[1].'</b> '; } die; }
?>
|
La funcion array_search devuelve un valor numérico, de modo que lo que hace eso es que si no es ningún valor numérico, morir el código asi evitamos algún posible ataque ^__^
Y bien, supongamos que tenemos el script ya montado, pero.. ¿¿¿y si subo 2 veces el archivo con el mismo nombre??? o_o Se sobreescribiria el anterior perdiendolo, de modo que lo que ahora haremos será verificar si existe, en caso de existir, se codificará el nombre con base64 multiplicado por un algoritmo matemático para que no haya coincidencia con cualquier que se suba.
Codigo:
1 2 3 4 5 6 7 8 9
|
<?php
#
# Comprobamos si ya existe algún archivo con el mismo nombre en la carpeta $dname, en caso afirmativo se cambia el nombre del archivo
#
echo 'Subiendo archivo <b>'.$_FILES['file']['name'].'</b> al directorio '.$dname.'<br><br>';
if(is_file($dname.'/'.stripslashes(base64_encode($_FILES['file']['name'])).'.'.$ext)){
$_FILES['file']['name'] = base64_encode(bin2hex($_FILES['file']['name'])*rand(-99999999999999,99999999999999)); # En este caso preferí en vez de un algoritmo, un número al azar
}
?>
|
Tras esto, debemos comprobar que no ha existido error alguno en la subida del archivo, de modo que el archivo ya esté en la carpeta.
Codigo:
1 2 3 4 5 6 7 8 9 10 11 12
|
<?php
#
# Comprobamos que no ha habido ningún error en la subida del archivo y si se ha subido el archivo correctamente #
#
if($_FILES['file']['error'] == 0 && is_uploaded_file($_FILES['file']['tmp_name'])){
echo '¡No ha habido errores en la subida del archivo!<br>';
}elseif($_FILES['file']['error'] == 2){
echo "<b><font color=\"#FF0000\">Error:</font></b> El tamaño del archivo supera el peso máximo establecido de: <b>".round(($fsize/1048576),1).'</b> megabytes.<br>';
}else{
echo "<b><font color=\"#FF0000\">Error</font></b> en la subida del archivo.";
}
?>
|
Una vez el archivo este subido a la carpeta temporal, lo movemos a la carpeta que hayas puesto en $dname.
Codigo:
1 2 3 4 5 6 7 8 9 10 11
|
<?php
#
# Ahora movemos el archivo desde la carpeta temp hasta la carpeta $dname #
#
if(move_uploaded_file($_FILES['file']['tmp_name'],$dname.'/'.stripslashes(base64_encode($_FILES['file']['name'])).'.'.$ext)){
echo "<b><font color=\"#00CC66\">OK</font></b> El archivo se ha subido satisfactoriamente.<br><a href=\"$durl/$dname/".stripslashes(base64_encode($_FILES['file']['name'])).'.'.$ext."\">".$_FILES['file']['name']."</a>";
setcookie('mctekkuploadfile',stripslashes(base64_encode($_FILES['file']['name'])),time()+$ftime);
}else{
echo "<b><font color=\"#FF0000\">Error:</font></b> No se ha podido subir el archivo.";
}
?>
|
Y ya, por último y para terminar con nuestro pequeño uploader, cerramos las etiquetas abiertas en php, ahora solo hay una, que es 'else' que envia un mensaje con el tiempo de espera entre subida y subida, y una llave tras el último pedazo de código html que cierra la tabla.
Codigo:
1 2 3
|
<?php}else{
echo 'Ya has subido un archivo, debes esperar <b>'.(int)($ftime/60).'</b> minutos antes de subir otro archivo.'; }
?>
|
Code:
<!-- Cerramos la tabla--> </span></font></td></tr></table></div> <!-- Fin del código html --> |
Codigo:
Espero que algún dia les pueda servir de algo este pequeño tutorial, es el primero que publico, esperaré los comentarios y posibles errores ^__^
Saludos: Bline 8)