Ver índice
Funciones FTP

        Ocultar índice  

   Índice de contenidos
   Instalación en Windows
   Instalación en Ubuntu
   Servidores seguros
   Páginas dinámicas
   Sintaxis básica
   Operaciones
   Arrays
   Formatos de presentación
   Operadores
   Bucles
   Extraer y ord. información
   Funciones
   Ficheros externos
   Imágenes dinámicas
   Gestión de directorios
   Cookies y sesiones
   Clases y objetos
   Ficheros en formato PDF
   Bases de datos MySQL
   PHP y XML
   PDO - Bases SQLite / MySQL
   MySQL a traves de misqli
   Algo de JavaScript y AJAX



Requisitos del sistema

El uso de estas funciones requiere que PHP tenga activada la opción FTP (enabled), que en nuestro caso está activada en la configuración por defecto, tal como puedes ver a través de tu info.php, que tendrá un apartado idéntico al que observamos en la siguiente imagen.

Esto en cuanto a PHP. Pero además de esta configuración será imprescindible disponer de un servidor FTP accesible y activo. En este tipo de transferencias intervienen dos servidores: el servidor HTTP (nuestro Apache) y el servidor FTP, cuyo procedimiento de instalación y configuración hemos descrito en el apartado Servidor de FTP. Antes de poder utilizar las funciones que aquí describimos deberás tener instalado y activo el servidor FTP que allí se describe.

Nos conviene tener muy presente que esta versión de PHP parece no admitir localhost como nombre de servidor (en la versión 4 esto no ocurría) y que por esa razón hemos de referirnos al servidor FTP mediante su dirección IP (127.0.0.1, valor por defecto para nuestro servidor de pruebas en modo local) y que hemos creado diferentes usuarios (con privilegios distintos) entre ellos admin.

Transferencias FTP

En la página anterior hemos hablado de la manera de transferir información entre el ordenador de un usuario y un servidor web. Aquí trataremos algo –similar a primera vista– un poco distinto. Es el caso de las transferencias –en los dos sentidosentre servidores (un servidor HTTP y un servidor FTP).

En la configuración descrita en la instalación del servidor FTP hemos establecido que ambos servidores tengan sus root en el mismo equipo, pero esa no es la única opción posible. Es totalmente factible que uno de los servidores esté alojado en un equipo situado físicamente en Londres y el otro lo esté en Sydney, por poner un ejemplo de lugares distantes. Imaginemos que todo esto es cierto.

Los dos primeros pasos para poder utilizar las funciones FTP han de ser: abrir la conexión y pasar el login. El último sería cerrar la conexión.

Abrir la conexión

$identificador=ftp_connect (host,puerto)

Esta función –en la que host es una cadena con el nombre del servidor FTP (no te olvides de ponerlo entre comillas) y puerto es el número del puerto a través del cual se efectúa la conexión FTP– abre una conexión con el servidor FTP.

Si se omite puerto se asigna por defecto el valor 21 que es el habitual para este tipo de servidores.

La variable $identificador recogerá un identificador de conexión que será utilizado por las demás funciones.

«Loguearse»

Utilizaremos este término del argot informático¿horrible, verdad?– para referirnos al hecho de que el usuario se acredite como autorizado en el servidor FTP.

ftp_login($identificador,usuario,contraseña)

Una vez abierta la conexión es preciso comenzar la sesión utilizando la función ftp_login con los siguientes parámetros:

Esta función devuelve un valor booleano que será 1 en el caso en que se inicie la sesión correctamente o NUL si no lo hace.

Cerrar la conexión

Mediante la función:

ftp_quit($x)

se cierra la conexión abierta con el identificador indicado en la variable $identificador.

<?php
# conexión con el servidor FTP
if($x=@ftp_connect ("127.0.0.1",21)){
    echo "Conexión FTP activada<br>";
}else{
    echo "No se activo lo conexión FTP<br>";
}
# registro de usuario
if(@ftp_login($x,"super","superi")){
    echo "El login y la password han sido aceptados";
}else{
    echo "Error en login o password";
}
#desconexión
ftp_quit($x);
?>

ejemplo180.php

Gestión de directorios en el servidor FTP

Una vez logueados y con la conexión activa, ya podremos utilizar funciones FTP tales como:

ftp_cdup($identificador)

Nos sitúa en el directorio raíz del servidor FTP.

ftp_pwd($identificador)

Devuelve una cadena con el nombre del directorio actual.

ftp_chdir($identificador, otro_directorio)

Cambia el acceso del directorio actual al especificado por la cadena otro_directorio, en caso de que exista.

ftp_pwd($identificador)

Devuelve una cadena que contiene el nombre del directorio actual.

ftp_mkdir($identificador, nuevo_directorio)

Crea un subdirectorio –en el directorio actual– cuyo nombre es el nombre indicado en la cadena nuevo_directorio.

ftp_rmdir($identificador, nombre_directorio)

Borra el directorio especificado en la cadena nombre_directorio. Para que un directorio pueda ser borrado se requiere que esté vacío y que sea un subdirectorio del directorio actual.

Información sobre los contenidos de los directorios del servidor FTP

ftp_nlist($identificador, nombre_directorio)

Devuelve una array escalar con los nombres de los ficheros y subdirectorios contenidos en el directorio que se indica en nombre_directorio. Si se trata del directorio actual, el parámetro nombre_directorio puede especificarse como una cadena vacía ("").

Si la información se refiere a un subdirectorio del actual bastará con poner su nombre como valor del parámetro nombre_directorio. En cualquier otro caso nombre_directorio contendrá la ruta completa.

ftp_rawlist($identificador, nombre_directorio)

Igual que la función anterior, ftp_rawlist también devuelve un array escalar, pero en este caso con información ampliada. Este array detalla, además del nombre del fichero, el tamaño, el tipo, la fecha de la última modificación y los permisos de lectura y/o escritura.

<?php
if($x=@ftp_connect ("127.0.0.1",21)){
    echo "Conexión FTP activada<br>";
}else{
    echo "No se activo lo conexión FTP";
}
if(@ftp_login($x,"webmaster","webmaster")){
    echo "El login y la password han sido aceptados<BR><BR>";
}else{
    echo "Error en login o password";
}
$lista=ftp_nlist($x,"/php/images");
foreach($lista as $c=>$v){
    print "Indice: ".$c." Valor: ".$v."<br>";
}
print "<H1>Lista completa</H1>";
$listacompleta=ftp_rawlist($x,"/php/images");
foreach($listacompleta as $c=>$v){
     print "Indice: ".$c." Valor:".$v."</br>";
}
ftp_quit($x);
?>
ejemplo181.php

El resultado de la ejecución del script anterior podría producir una salida similar a esta:

Tal como puedes ver en la imagen, la cadena devuelta por la función ftp_rawlist tiene dos resultados distintos. La primera de las cadenas comienza por lo cual indica que se trata de un archivo y documento. En el segundo de los casos, se primer carácter es d e indica que se trata de un directorio.

Los nueve caracteres siguientes especifican los permisos de acceso a los ficheros y/o directorios. Se subdividen en tres bloques de igual tamaño que corresponden a los tres niveles de usuarios habituales en sistemas Unix/Linux (propietario, grupo y resto de usuarios). Para nuestros propósitos bastará con que consideremos los privilegios del primer bloque, es decir los del propietario.

El primero carácter de cada bloque sólo puede ser r ó . Si se trata de un fichero y está marcado con r indica que se permite el acceso a él en modo lectura y si se trata de un directorio indica que está permitida la visualización de su contenido.

El segundo de los caracteres (puede ser w ó ) indica, si se trata de un fichero, que está permitida la modificación del fichero. Cuando se trata de un directorio significa que se pueden añadir o suprimir ficheros.

El tercero de los caracteres indicaría (x ó ) que el fichero -si se trata de un ejecutable- tiene permisos para ser ejecutado. Cuando se trata de un directorio, indica que pueden conocerse los atributos de los ficheros que contiene y que está permitido el acceso a él y a sus subdirectorios.

El signo significa la negación del atributo en todas las opciones.

El siguiente carácter, el número 1, está asociado con sistemas Linux/Unix e indicaría el número de vínculos duros contra el archivo, que es otra cosa que una forma de asignar nombres distintos a un mismo fichero.

Los dos grupos siguientes -parece que no demasiado relevantes para nuestros propósitos- son los nombres del usuario y grupo al que pertenece. A continuación aparece el tamaño del archivo (cero si se trata de un directorio), la fecha y hora de su creación y el nombre del archivo o directorio.

Transferencia de ficheros

Las transferencias de ficheros pueden realizarse en ambos sentidos.

Desde el servidor FTP hasta el servidor HTTP

Mediante la función:

ftp_get( $identificador, nombre_en_servidor_web, nombre_en_servidor_ftp, modo)

se transfiere un fichero desde un servidor FTP hasta un directorio del servidor HTTP en el que se está ejecutando PHP. La cadena nombre_en_servidor_web contiene el nombre con el que el fichero será copiado en el directorio actual del servidor web y la cadena nombre_en_servidor_ftp contiene el nombre (incluyendo el path) que tiene (en el servidor FTP) el fichero que debe ser trasferido. El parámetro modo puede contener uno de estos valores: FTP_ASCII o FTP_BINARY

Desde el servidor HTTP hasta el servidor FTP

Para realizar transferencias en sentido opuesto al anterior se utiliza la siguiente sintaxis:

ftp_put($identificador, nombre_en_servidor_ftp, nombre_en_servidor_web, modo)

Se comporta de forma idéntica a la función anterior. La cadena nombre_en_servidor_ftp sigue siendo el nombre y el path del servidor FTP (donde vamos a copiar el fichero) y nombre_en_servidor_web contiene el nombre del fichero en el servidor web (origen de la transferencia).

Modificación de ficheros en el servidor FTP

ftp_rename($identificador,nombre_actual,nuevo_nombre)

Cambia el nombre del fichero nombre_actual por el indicado en la cadena nuevo_nombre.

ftp_delete($identificador,nombre_fichero)

Elimina -en el servidor FTP- el fichero indicado en la cadena nombre_fichero.

Información sobre ficheros del en el servidor FTP

ftp_size($identificador,nombre_fichero)

Devuelve el tamaño (en bytes) del fichero que se indica en la cadena nombre_fichero.

ftp_mdtm($identificador,nombre_fichero)

Esta función devuelve la fecha de la última modificación del fichero indicado en la cadena nombre_fichero. Esta fecha se indica en tiempo Unix.

Un ejemplo de uso de las funciones FTP

<?php
# Conexión con el el servidor ftp utilizando su dirección IP 
if(!$x=@ftp_connect ("127.0.0.1",21)){
    echo "No se activo lo conexión FTP";
	exit();
}
# Identificación de usuario webmaster (manejaremos ficheros en Apache)
if(!@ftp_login($x,"webmaster","webmaster")){
    echo "Error en login o password";
	exit();
}
/* comprobamos el nombre del directorio actual del servidor FTP
que será el root correspondiente al usuario registrado (aparecrá /) */
echo "El directorio actual es: ",ftp_pwd($x),"<br>";
/* intentamos cambiar a un subdirectorio indicando la ruta absoluta
partiendo del directorio root del usuario actual.
En caso de error (ruta incorrecta o falta de permisos de accesos
nos daría un mensaje de error. Si el cambio tiene éxito nos indicaría
el nombre del nuevo directorio */
if(!@ftp_chdir($x,"/miphp/pdf")){
    print "No tienes permisos de acceso a este directorio<br>";
    print "o la ruta es incorrecta.¡Comprueba los datos!<br>";
  }else{
    echo "Hemos cambiado al directorio: ",ftp_pwd($x),"<br>";
}
# comprobamos el nombre del sistema operativo del servidor de FTP
echo "El S.O: del servidor FTP es: ",ftp_systype ($x),"<br>";
/* obtenemos una matriz conteniendo la lista de ficheros y directorios
 del subdirectorio "miphp/fuentes" del del directorio actual*/
$lista=ftp_nlist($x,"/miphp/fuentes");
# escribimos la lista de ficheros contenidos en ese directorio
echo "Lista de ficheros del subdirectorio miphp/fuentes<br>";
     foreach ($lista as $valor){
           echo $valor,"<br>";
     } 
# obtenemos una lista completa de los contenidos de ese subdirectorio
$lista=ftp_rawlist($x,"/miphp/fuentes");
# ordenamos el array que contiene la lista anterior
sort($lista);
echo "Contenidos del subdirectorio miphp/fuentes<br>";
/* extrae los elementos del array eliminando los espacios repetidos
mediante la funcion preg_replace en la que \s+ indica uno o más espacios
  que serán sustituidos por uno solo (' ') */
foreach($lista as $v){
          $v=preg_replace('/\s+/', ' ', $v);
       # imprimimos la cadena completa
          print "<br><br><br>".$v."<br>";
       # convertimos la cadena en un array
       # utilizando los espacios como separadores
          $extrae=explode(" ",$v);
       # leemos los elementos del array y comentamos sus valores
   foreach($extrae as $indice=>$cont){
     switch($indice){
       case 0:
         print "El elemento de indice".$indice." es: ".$cont."<br>";
         if (substr($cont,0,1)=="d"){
            print "Es un directorio<br>";
         }elseif(substr($cont,0,1)=="-"){
            print "Es un fichero<br>";
         }
		 if (substr($cont,1,1)=="r"){
            print "Tiene permisos de LECTURA<br>";
         }elseif(substr($cont,1,1)=="-"){
            print "No tiene permisos de LECTURA<br>";
         }
        if (substr($cont,2,1)=="w"){
            print "Tiene permisos de ESCRITURA<br>";
         }elseif(substr($cont,2,1)=="-"){
            print "No tiene permisos de ESCRITURA<br>";
         }
       break;
       case 4:
           print "El tamaño de este fichero es: ".$cont." bytes<br>";
       break;
       case 8:
           print "El nombre del fichero o directorio es: ".$cont."<br>";
       break;
     }
   }
}
# regresamos al directorio miphp
ftp_chdir($x,"/miphp/");
/* creamos un subdirectorio (del directorio actual que es miphp)
con nombre experimento anteponiendo @# para evitar mensajes de error
en caso de que ya existiera */
@ftp_mkdir($x,"experimento");
/* copiamos el fichero enol.jpg desde el directorio que se indica
   en el tercer parámetro (miphp)
   al directorio del servidor FTP que se indica
   en el segundo parámetro. Le ponemos por nombre lago_enol.jpg */
ftp_put($x, "../miphp/experimento/lago_enol.jpg",
                       "../miphp/enol.jpg",FTP_BINARY);
# obtenemos el tamaño del fichero transferido
echo "El tamaño de fichero tranferidos es: ",
ftp_size($x,"../miphp/experimento/lago_enol.jpg")," bytes<br>";
/* escribimos la fecha de la última modificación del fichero transferido
 que coincidirá con la fecha y hora en la que se realizó la transferencia.
 Convertimos a formato de fecha convencional el tiempo UNIX que devuelve
 la función ftp_mdtm */
print "La fecha de modificacion del fichero es:";
print date("d-m-Y H:i:s",ftp_mdtm($x,"./experimento/lago_enol.jpg"));
# cambiamos el nombre del fichero lago_enol.jpg por lago_covadonga.jpg
# en el servidor FTP
@ftp_rename($x,"./experimento/lago_enol.jpg",
              "./experimento/lago_covadonga.jpg");
/* creamos un enlace de descarga directa del fichero haciendo una llamada
   mediante el protocolo ftp:// utilizando la sintaxis:
   ftp://usuario:contraseña@nombre del servidor
   seguidos de la ruta (en el servidor FTP) y el nombre del fichero */
print "<BR><a href='ftp://webmaster:webmaster@localhost";
print "/miphp/experimento/lago_covadonga.jpg'> Descargar</a>";
/* transferimos al directorio miphp con nombre liborio.jpg
   un fichero procedente del directorio experimento
   cuyo nombre es lago_covadonga.jpg*/
ftp_get($x,"../miphp/liborio.jpg",
                        "./experimento/lago_covadonga.jpg",FTP_ASCII);
/* comprimimos un fichero alojado en miphp
      para transferirlo comprimido al servidor FTP */
     #empezamos leyendo el fichero y guardándolo en una cadena
      $cadena=""; // inicializamos la variable con una cadena vacía
    $f1=fopen("cabina.jpg","r");
          while (!feof($f1)) {
                  $cadena .= fgets($f1,1024);
            }
     fclose($f1);
    # comprimimos la cadena obtenida del fichero anterior
          $c1=gzencode($cadena,3,FORCE_GZIP);
    # guardamos la cadena comprimida en un fichero
          $f=fopen("cabina.jpg.gz","w");
          fwrite($f,$c1);
          fclose($f);
/* al servidor el fichero comprimido. No es necesario indicar
  la ruta actual ya que ha sido creado en el mismo directorio
  en el que se está ejecutando el script */
ftp_put($x, "./experimento/cabina.jpg.gz",
              "cabina.jpg.gz",FTP_BINARY);
	#eliminamos el fichero comprimido del directorio miphp
 unlink("cabina.jpg.gz");
 # cerramos la conexión con el servidor ftp
ftp_quit($x);
# establecemos un enlace de descarga para el fichero comprimido
print "<BR><a href='ftp://webmaster:webmaster@localhost";
print "/miphp/experimento/cabina.jpg.gz'>Descarga comprimido</a>";
?>

  ¡Cuidado!  

Observa los path de los ejemplos. Al anteponer ../ estaremos indicando una ruta absoluta desde al root de servidor FTP y con ./ aludimos a un subdirectorio del actual.

Si vas a utilizar el ejemplo anterior presta mucha atención a los nombres de los directorios y adecúalos a la configuración de tu servidor.
Al ejecutar el script del ejemplo anterior por segunda vez (sobre Linux Ubuntu) puede aparecerte un mensaje de error del tipo overwrite permission denied.

Este problema puede ser causado por un defecto de configuración del sevidor FTP. Hemos podido comprobar que, algunas veces, por una extraña razón, aparecen en el fichero de configuración dos líneas segudas dicendo AllowOverwrite Off y AllowOverwrite On. La configuración correcta es AllowOverwrite On (para permitir sobreescribir). Bastaría con eliminar la línea marcada con Off (o reemplazar el Off por On) para solventar el problema.