¡Advertencia!
Este tema no ha tenido respuestas en más de un mes. Recuerda que si deseas añadir una nueva debes cumplir con las normas de la web.
Archivos.

¿Qué explicaré?
Carga de ficheros (Tanto permisos, nombre, tipo, tamaño, etc) y funciones acerca de archivos (copiar, mover, eliminar, crear, etc).

Quisiera comenzar explicando la diferencia entre $_FILES y $HTTP_POST_FILES.
Las dos son variables que contienen la misma información cuando se hace una carga a el script (en este caso, subir un archivo), pero la diferencia es que $HTTP_POST_FILES no es una variable "superglobal", con esto quiero decir que tál vez contenga la misma información del fichero pero no se puede acceder en todo el script a ella sin hacer global $fichero, por otro lado, $_FILES si es una "superglobal" que está disponible ó se puede acceder a ella durante y/ó en cualquier parte del script, y según leí (esto no lo tenía en cuenta) $_FILES esta disponible desde la versión 4.1.0 por lo que $HTTP_POST_FILES quedo completamente "nulled" en esas versiones.

Tomando de siempre de ejemplo en este caso el siguiente uploader:


<form action="subir.php" method="post" enctype="multipart/form-data">
<b>Archivo: </b>
<br>
<input name="fichero" type="file">
<br>
<input type="submit" value="Enviar">
</form> 


Comenzemos, las variables príncipales de $_FILES son las siguientes (noten que fichero es el nombre del input type por lo que en $_FILES el primer "valor del array" es el nombre del input, y como mencioné anteriormente, en este caso es fichero:
$_FILES['fichero']['tmp_name'] = Muestra el nombre "temporal" del archivo, puede ser parecido a phpC2.tmp, siempre varian.
$_FILES["fichero"]["name"] = Muestra el nombre original del archivo, en este caso muestra tutorial.txt.
$_FILES["fichero"]["type"] = Muestra el tipo del archivo, en este caso es text/plain pero hay image/jpeg, stream, etc, todo depende si es ejecutable, imagen, texto plano, script, entre otros.
$_FILES["fichero"]["size"] = Muestra el tamaño de archivo en bytes, pueden hacer una operación divisoria de / 1024 para ir convirtiendolo a kb, mb, gb, etc.

<?php
echo $_FILES['fichero']['tmp_name']."<br />"; //Es el archivo temporal para subir al servidor
echo $_FILES["fichero"]["name"]."<br />"; //Es el nombre del archivo a subir al servidor
echo $_FILES["fichero"]["type"]."<br />"; //Es el tipo (mime) del archivo a subir al servidor
echo $_FILES["fichero"]["size"]."<br />"; //Es el tamano (en bytes) del archivo a subir al servidor
/*
Nota: Puedes hacer $_FILES["fichero"]["size"] / 1024 para ir en escala de bytes, kb, mb, etc.
Daria como resultado:
C:\WINDOWS\Temp\phpC2.tmp => Temporal
tutorial.txt => Nombre
text/plain => Tipo (mime)
0 => Peso
*/
?>


Como pudieron observar, esas son los valores del array $_FILES que se utilizan para hacer un uploader, solo tiene que coincidir el nombre del input con el del script (en este caso; fichero).

Para hacer la "copia" ó mejor dicho "mover" el archivo al lugar definitivo en donde se almacenará el fichero, se utiliza la función move_uploaded_file(); creo que el nombre lo dice todo.
move_uploaded_file() recibe dos parámetros, el primero es el nombre temporal del archivo a subir, y el segundo es en donde se almacenará, pueden notar que tengo una variable llamada $path que es donde indico a que carpeta subiré los archivos.

Ejemplo:


<?php
$path = "files/";
$temporal = $_FILES['fichero']['tmp_name'];
$archivo = basename($_FILES["fichero"]["name"]);
if( (move_uploaded_file($temporal,$path.$archivo))){
echo "Archivo subido correctamente.";
}else{
echo "Hubo un error en la carga del archivo.";
}
?>


Aqui pueden utilizar simplemente $_FILES["fichero"]["name"] sin necesidad del basename ya que la funcion basename() solo vota el nombre de fichero.
-----------------------------------------------------------
Copiar un archivo
-----------------------------------------------------------
Para copiar un archivo se utiliza la función copy() que recibe dos parámetros, el fichero original y la ruta a donde se copiará, ejemplo (Tomando de ejemplo el archivo tutorial.txt que anteriormente subimos):

<?php
$path = "files/";
$archivo = basename($_FILES["fichero"]["name"]);
copy($path.$archivo, $path."tutorial_copia.txt");
/*
Daria:
files/tutorial_copia.txt
*/
?>


Recuerden que para copiar un archivo se necesita "determinar" el directorio en donde se encuentra el archivo, inclusive se puede copiar de un directorio a otro.
-----------------------------------------------------------
Comprobar si un fichero/directorio existe
-----------------------------------------------------------
Esto les servirá muchos a aquellos que tengan su modulación digamos "index.php?page=home.php", que prácticamente se incluye la página que se obtiene por get y si no la filtran son vulnerables a RFI/LFI, si no tiene modulación igual funciona, existe una función llamada file_exists() que comprueba la existencia de un fichero, tiene un parámetros que por lógica deben suponer que se trata del archivo, en este caso comprobarémos la existencia del archivo "tutorial_copia.txt".

<?php
if (file_exists("./files/tutorial_copia.txt")){
echo "Si existe";
}else{
echo "No existe";
}
/*
Devolveria:
Si existe, pero si cambiamos tutorial_copia por loquesea.txt tiraria no existe porque en este caso no tenemos ese fichero en el servidor.
*/
?>


Un ejemplo de la modulación con GET filtrando el archivo (ya que lo mencioné) sería:

<?php
$pagina = strip_tags(stripslashes($_GET['page']));
if (file_exists($pagina)){
include ($pagina);
}else{
echo "No intentes bugear, la pagina no existe, se envio un correo al administrador con tu IP";
}
?>

-----------------------------------------------------------
Crear un directorio
-----------------------------------------------------------
Para crear un directorio existe la función mkdir() en donde mk significa make/crear y dir es directory/directorio, para utilizar esta función se necesitan dos parámetros, el nombre del directorio y los permisos que tendrá el directorio.

<?php
mkdir("/dir", "0777");
/*
Daria:
path_base/dir/ con permisos de escritura, lectura y ejecucion (0777).
*/
?>


Aquí se puede utilizar la función "file_exists()" para comprobar si existe el directorio, ejemplo:

<?php
if (file_exists("./files")){
echo "Si existe";
}else{
mkdir("/files", "0777");
}
/*
Daria:
Si existe el directorio te da un aviso de que existe, si no existe lo crea con permisos de 0777.
*/
?>

-----------------------------------------------------------
Revisar un directorio y contar archivos
-----------------------------------------------------------
Para ello utilizarémos 2 funciones, scandir() y count() , scandir() ocupa un parámetro (el directorio a escanear) y count ocupa igualmente un parámetro, lo que contará:

<?php
$directorio = "files/";
$contador = scandir($directorio);
$total = count($contador);
/*
Si hacemos un var_dump() para mostrar todas los valores nos mostraría todos los archivos que existen en el directorio, en este
caso solo existe 1 (tutorial.txt);
*/
?>

Esto puede ser algo fácil al momento de querer saber que archivos estan en una carpeta determinada, pero casi no se utiliza.
-----------------------------------------------------------
Eliminar un archivo/directorio
-----------------------------------------------------------
Para eliminar un archivo se utiliza la función unlink(), y por otro lado, para eliminar un directorio se utiliza la función rmdir(), las dos funciones tienen un solo parámetros que es la dirección del archivo/directorio.
rmdir() solo permite borrar si el directorio esta vacío:


<?php
$archivo = "tutorial.txt";
$directorio = "files/";
rmdir($directorio); //En este caso no se eliminaría porque existe tutorial.txt
unlink($directorio.$archivo); //Eliminamos files/tutorial.txt
?>

Entonces, ¿Qué hacer si la carpeta no está vacía pero queremos eliminarla? Fácil, utilizamos la función scandir() y count() y la implementamos con un bucle for:
For: Es un bucle en donde a diferencia de foreach, indicamos el número de "ciclos" que se repetirá:


<?php
$directorio = "files/";
$files = scandir($directorio); //Escaneamos el directorio
$num = count($files ); //Contamos el numero de archivos
for ($i=0; $i<=$num; $i++) { 
@unlink ($directorio.$files [$i]); //Ponemos un @ al inicio para evitar mostrar error en pantalla.
}
@rmdir ($directorio); //Ponemos un @ al inicio para evitar mostrar error en pantalla.
?> 

Que hacemos con el for:
Indicamos que mientras $i sea menor que el número de archivos, $i irá aumentando de uno en uno, prácticamente si el número de archivos es 1, sería $i=0; $i<=1; $i++, para eso es el bucle for, para indicarle cuantas veces se repetirá el ciclo. Entonces como no sabemos el número de archivos, los contamos con count() y se creará un array con el número total de archivos, así que al poner $files[$i] y anteriormente indicando en el bucle for que $i irá aumentando de uno en uno cada vez hasta que llegue al número de archivos, se eliminará de uno por uno los archivos. Despúes se elimina el directorio vacío.
-----------------------------------------------------------
Renombrar un archivo/directorio
-----------------------------------------------------------
Para renombrar un archivo/directorio utilizamos la función rename() en donde solo necesitamos dos parámetro; el nombre original y el nombre a cambiar.

<?php
$file = "files/tutorial.txt";
rename ($file , "files/tutoriales_2.txt");
?>

-----------------------------------------------------------
Comprobar permisos de archivo
-----------------------------------------------------------
Para comprobar los permisos de archivo (saber si es ejecutable, etc) utilizarémos tres funciones:
is_writable($archivo); = Comprueba si se puede escribir.
is_readable($archivo); = Comprueba si se puede leer.
is_executable($archivo); = Comprueba si se puede ejecutar.
-----------------------------------------------------------
Archivos de texto
-----------------------------------------------------------
Cabe mencionar que no solo se puede para archivos de texto, si no para html, php, etc, solo explicaré una función y las demás en comentarios porque creo que podrán entender perfectamente sin necesidad de que explique de una por una.
Comenzaré explicando los permisos de archivos.

'r' Solo lectura, ubicará el puntero al inicio de todo el archivo.
'r+'  Solo lectura y escritura, ubicará el puntero al inicio de todo el archivo.
'w' Solo escritura, si el archivo no existe intentará crearlo.
'w+' Solo escritura y lectura, si el archivo no existe intentará crearlo
'a' Solo escritura, ubicará el puntero al final de todo el archivo y si no existe intentará crearlo.
'a+' Solo escritura y lectura, ubicará el puntero al final de todo el archivo y si no existe intentará crearlo.
'x' Solo escritura, si el archivo ya existe devolverá un FALSE, si no existe intentará crearlo.
'x+' Solo escritura y lectura, si el archivo ya existe devolverá un FALSE, si no existe intentará crearlo.


Ahora, para abrir un archivo se utiliza la función fopen() el cual recibe dos parámetros, el archivo a abrir y los permisos que le darémos, despues viene fwrite() quien igualmente recibe dos parámetros, el fopen y lo que se intentará escribir en el archivo, y finalmente viene fclose() que solo recibe un parámetro a diferencia de los otros dos, solo recibe el fwrite quien ya trae el fopen.

<?php
$file = fopen("tutorial.txt", 'a+');
fwrite($file, "Este es un tutorial de PHP hecho por Xt3mP"); //Se puede utilizar fputs() hacen practicamente lo mismo.
fclose($file)
/*
Daria:
tutorial.txt
Este es un tutorial de PHP hecho por Xt3mP
*/
?>


Se pueden hacer saltos de línea pero podrás identificarlas con \n.
-----------------------------------------------------------
Bueno, esto ha sido todo por este tutorial, estoy un poco cansado y necesito fumar, cualquier error que haya tenido ó parecido favor de avisarme para acomodarlo.
Saludos.

¡Soy el fantasma de Habtium! Me dedico a reemplazar aquellas cuentas que han sido eliminadas. 👻
Muy pero muy interesante eh. Mañana mismo me dedicaré un ratito para comprender esto mejor, leí las primeras partes y de paso quería hacer una pequeñísima aclaración para los interesados:

Si bien entendieron o leyeron un poco el tutorial de "Arrays", pueden observar que la variable superglobal $_FILES es una matriz.
$_FILES tiene una fila y hasta donde yo recuerde, 6 columnas.

Graficamente:

		+----------+
		| variable | <= Inicio de columna
		+----------+
		|   name   |
		+----------+
		|   type   |
		+----------+
		| tmp_name |
		+----------+
		|   error  |
		+----------+
		|   size   |
		+----------+


Donde "variable" es el nombre que le asignes a dicho 'fichero' como muy bien explicó él.



Estos temas a mí me parecen realmente interesante, y de paso nos vamos dando cuenta que si uno quiere programar, independientemente el lenguaje de programación, debe conocer los fundamentos básicos de la programación. Cosas como la declaración de variables, operadores aritméticos/lógicos, estructuras de control alternativas/ciclos y arreglos vectoriales/matrices. Todo gira entorno a ello
Exáctamente, olvide mencionar error y no me enfoqué a como hacer un uploader seguro porque sería ilógico aprender a "parcharlo" para que no se pueda bypassear sin saber crear uno normal, en otro tutorial que haré lo pondré, y sí Physlet, a mi tambien se me hace sumamente interesante todo esto, y me encantan los "dobles arrays" (así les digo xD).

$yo["Xt3mP"]["MSN"]; O sí! hahaha, saludos.

¡Soy el fantasma de Habtium! Me dedico a reemplazar aquellas cuentas que han sido eliminadas. 👻
Exáctamente, olvide mencionar error y no me enfoqué a como hacer un uploader seguro porque sería ilógico aprender a "parcharlo" para que no se pueda bypassear sin saber crear uno normal, en otro tutorial que haré lo pondré, y sí Physlet, a mi tambien se me hace sumamente interesante todo esto, y me encantan los "dobles arrays" (así les digo xD).

$yo["Xt3mP"]["MSN"]; O sí! hahaha, saludos.

Algo curioso: esos "dobles arrays" los comprendo más rápido cuando son números. xDDDDD

Algo curioso: esos "dobles arrays" los comprendo más rápido cuando son números. xDDDDD


Hahaha si, suele pasar, pero cuando llevas rato programando con strings en los arrays multidimensionales los diferencio mucho mejor xD, por ejemplo $info["user"]["status"]; y asi me guío más fácilmente, aunque solo los utilizo cuando realmente es necesario xD.

¡Soy el fantasma de Habtium! Me dedico a reemplazar aquellas cuentas que han sido eliminadas. 👻
¿esto podría servir para crear nuestro propio FTP?
¿esto podría servir para crear nuestro propio FTP?

Exactamente. Con esto podrías hacer una especie de Web FTP como el de miarroba.

Exactamente. Con esto podrías hacer una especie de Web FTP como el de miarroba.


Tambien esto lo utilizan las famosas "shells" que prácticamente son como administradores de FTP vía on-line (no daré nombre de ninguna ya que entra en lo que es área de Defacing y no pienso explicar nada de Defacing en este foro), pero estaría bueno un "mini-proyecto" que sea prácticamente todo automatizado, como un FTP en PHP pero automatizado, reducido y efectivo.

Saludos.

¡Soy el fantasma de Habtium! Me dedico a reemplazar aquellas cuentas que han sido eliminadas. 👻