Gestiona tu FTP desde PHP

Las funcionalidades que nos puede ofrecer PHP son innumerables, y muchas de ellas puede llegar a ser muy desconocidas para los usuarios finales, como la forma de trabajar con el protocolo FTP mediante PHP. A lo largo de este tutorial, vamos a ir elaborando una serie de funcionalidades que nos permitirá realizar las funciones que realiza cualquier cliente FTP que podamos utiliza.

Lo primero que vamos a definir, serán las funcionalidades de nuestra clase incluirá. En nuestro caso serán:

  • Conexión al servidor
  • Crear una carpeta en el servidor
  • Subir un fichero
  • Cambiar de directorio
  • Recuperar el listado del directorio
  • Descargar un fichero

Lo siguiente que debemos de tener claro, es cuando debemos de utilizar una clase FTP. Nos podemos encontrar varios casos:

  • Automatizar la carga de imágenes, como una galería, a la página web de un cliente.
  • Realizar copias de seguridad fuera del sitio, mediante la transferencia de algún archivo.

Preparación

En este primer paso, lo que haremos será crearnos dos ficheros .PHP: index.php y ftp_class.php. En el primero de ellos será donde hagamos la creación del objeto de la clase ftp y la llamada a sus métodos y en el archivo ftp_class.php será donde tengamos todos los métodos relacionados con las acciones del FTP.

Creando la clase

La fuerza de la Programación Orientada a Objetos, nos permite crear completos códigos a la vez que es sencilla de utilizar. Nosotros podemos encapsular los datos de nuestra clase, y podemos utilizar esta una y otra vez sin la necesidad de tener que reescribir el código, únicamente debemos de hacer uso de la llamada a los métodos que forman parte de la clase.

Empecemos creando el esqueleto que formará nuestra clase FTP. Primero abrimos el archivo ftp_class.php y creamos nuestra clase. Le hemos dado el nombre de FTPClient, pero podéis darle el nombre que queráis.

A continuación creamos el método constructor, que será el que se utilice para la creación de los objetos de la clase, y donde podremos inicializar algunas variables que necesitemos en nuestra clase.

El código del archivo ftp_class.php hasta ahora, nos quedaría de la siguiente forma:

Class FTPClient{

         public function __construct() {        }

}

Variables de clase

En este paso, crearemos las variables de clase que utilizaremos en nuestra clase. Tendremos tres variables y todas ellas serán de tipo private, para que no puedan ser accesibles desde otras clases ajenas a la nuestra.

Las variables que utilizaremos serán las siguientes:

private $connectionId;
private $loginOk = false;
private $messageArray = array();

 

  • $connectionId será la variable donde almacenaremos nuestra cadena de conexión.
  • $loginOk nos indicará si estamos bien conectados
  • $messageArray será donde se almacenarán los distintos mensajes que devuelve la aplicación.

Método de registro de mensajes

En casi todos los métodos que vayamos desarrollando, utilizaremos un método, que llamaremos logMessage, que nos permitirá y almacenando en nuestro Array de mensajes los distintos mensajes que irá creando nuestra clase, para tener informado al usuario.

También crearemos otro método para poder recuperar el array donde vamos almacenando nuestros mensajes y al que llamaremos getMessages.

Después de esto, los dos métodos que crearemos serán:

private function logMessage($message){
        $this->messageArray[] = $message;
}
              
public function getMessages(){
        return $this->messageArray;
}

El segundo método lo hemos declarado público para que pueda ser accesible desde otras clases, ya que si lo ponemos como private, no podremos acceder a él, únicamente desde su clase, tal y como ocurrirá con el primer método.

Conexión

En este paso, añadiremos el método que nos permitirá realizar la conexión con el servidor FTP.

public function connect ($server, $ftpUser, $ftpPassword, $isPassive = false){
        // *** Creamos una conexión básica
        $this->connectionId = ftp_connect($server);

        // *** Login con usuario y contraseña
        $loginResult = ftp_login($this->connectionId, $ftpUser, $ftpPassword);

        // *** Indicamos si el método de conexión es pasivo o no (default off)
        ftp_pasv($this->connectionId, $isPassive);

        // *** Check conexión
        if ((!$this->connectionId) || (!$loginResult)) {
                $this->logMessage('FTP connection has failed!');
                $this->logMessage('Attempted to connect to ' . $server . ' for user ' . $ftpUser, true);
                return false;
        } else {
                $this->logMessage('Connected to ' . $server . ', for user ' . $ftpUser);
                $this->loginOk = true;
                return true;
        }
}

A nuestro método, le pasamos la información de conexión al servidor FTP (host, usuario y contraseña), además de indicarle si la conexión será pasiva o activa.

La primera línea del método, será realizar la conexión con el método ftp_connect, al que le indicamos el servidor. Nosotros almacenamos nuestra conexión en la variable $connectionId.

A continuación, nos logueamos mediante el método ftp_login, al que le pasamos nuestro ID de conexión que hemos obtenido anteriormente.

Después le debemos de indicar el tipo de conexión, si será en modo pasivo (por defecto) o en modo activo.

Si todo ha ido bien, registramos en nuestro array de mensajes que la conexión ha sido satisfactoria, pero si no existe el ID de conexión o no se ha podido realizar el logueo, entonces se almacenan los mensajes de error.

Llamada al objeto

Ahora que ya hemos dado algo de funcionalidad a nuestra clase, vamos a testearla para ver que por ahora todo funciona de forma correcta. Para ello nos abrimos nuestro fichero index.php y añadimos el siguiente código.

require_once 'ftp_class.php';
$server = '192.168.1.88';
$usuario = 'usuario';
$pass = 'password';

$ftp = new FTPClient();
$ftp->connect($server,$usuario,$pass);
$arrayMensajes = $ftp->getMessages();

foreach($arrayMensajes as $mensajes){
        echo $mensajes.'';
}

Lo primero que hacemos es añadir el fichero de nuestra clase FTP para poder crear luego nuestro objeto. A continuación creamos nuestro objeto FTP haciendo la llamada al constructor de la clase, y por último abrimos la conexión, llamando al método connect al que le pasamos el servidor, usuario y contraseña del servidor al que nos queremos conectar.

Por último, recuperamos los mensajes de la aplicación, y si todo ha ido bien, nos mostrará un mensaje indicando que la conexión se ha llevado a cabo.

Creando nuestro primer directorio

Ahora que hemos visto que nuestra clase funciona, vamos a darle algo de funcionalidad. Nuestro primer método que crearemos será makeDir, que nos permitirá crear directorios en el servidor. Este método recibirá un único parámetro, y que será el path y nombre de la carpeta.

Para crear el directorio, utilizaremos el método ftp_mkdir, al que se le indica nuestro id de conexión y el path del directorio a crear.

El código correspondiente a este método es el siguiente:

public function makeDir($directory){
        // *** Si la creación del directorio es satisfactoria..
        if (ftp_mkdir($this->connectionId, $directory)) {
                $this->logMessage('Directory "' . $directory . '" created successfully');
                return true;
        } else {
                // *** ...Sino, fallo.
                $this->logMessage('Failed creating directory "' . $directory . '"');
                return false;
        }
}

Ahora añadimos en el index.php la llamada al método para probar que todo funciona correctamente.

$dir = 'photos';      
// *** Crear directorio
$ftpObj->makeDir($dir); 

Subiendo un fichero

En este paso, lo que desarrollaremos será un método que nos permitirá realizar la subida de una foto a la carpeta que hemos creado. Cuando realizamos la subida de un archivo, debemos de indicar el tipo de fichero a subir, si es binario o ascii. Si estás subiendo un fichero de texto, debería de ser ascii, en cualquier otro caso, el tipo será binario.

Empezamos creando un array con todas las extensiones que deberían ser utilizados por el tipo ascii.

$asciiArray = array('txt','csv');

A continuación, recuperamos la extensión de nuestro fichero para saber si se trata de un fichero tipo ascii. Para ello, hacemos utilizamos el método explode de PHP y el “.” como delimitador. Explode nos devuelve un array con los valores, donde el último valor del array será la extensión. Para recuperarlo, utilizaremos el método end de PHP que devuelve el último elemento de un array.

$extension = end(explode('.', $fileFrom));

Una vez que tenemos la extensión, tenemos que ver si pertenece al array de extensiones que hemos creado. Para ello utilizamos el método in_array de PHP, que nos indica si un valor se encuentra dentro de un array.

in_array($extension, $asciiArray)

Si aparece en el listado, le asignaremos a la variable $mode el valor FTP_ASCII, en cualquier otro caso, el valor que le asignaremos será FTP_BINARY.

Para subir el fichero vía FTP, haremos uso del método ftp_put, al que le indicaremos el ID de nuestra conexión, la ruta donde la queremos subir, la ruta del fichero que queremos subir y el tipo de archivo que hemos determinado anteriormente.

El código completo de nuestro método será el siguiente.

public function uploadFile ($fileFrom, $fileTo){
        // *** miramos el tipo de fichero que es
        $asciiArray = array('txt', 'csv');
        $extension = end(explode('.', $fileFrom));
        if (in_array($extension, $asciiArray)) {
                $mode = FTP_ASCII;
        } else {
                $mode = FTP_BINARY;
        }

        // *** Subimos el fichero
        $upload = ftp_put($this->connectionId, $fileTo, $fileFrom, $mode);

        // *** Check el estado de la subida
        if (!$upload) {
                $this->logMessage('FTP upload has failed!');
                return false;
        } else {
                $this->logMessage('Uploaded "' . $fileFrom . '" as "' . $fileTo);
                return true;
        }
}

Para probar su funcionamiento, añadimos el siguiente código en nuestro index.php

$fileFrom = 'Invierno.jpg';
$fileTo = $dir . '/' . $fileFrom;

// *** hacemos la subida a nuestro directorio creado anteriormente
$ftpObj -> uploadFile($fileFrom, $fileTo);

Listando los ficheros

En este paso, lo que vamos ha desarrollar será una función que nos permita navegar por el directorio que hemos creado, para listar su contenido.

Crearemos el método changeDir que hace uso del método de PHP ftp_chdir que nos permite cambiar el actual directorio del servidor. El código del método es el siguiente.

public function changeDir($directory){
        if (ftp_chdir($this->connectionId, $directory)) {
                $this->logMessage('Current directory is now: ' . ftp_pwd($this->connectionId));
                return true;
        } else {
                $this->logMessage('Couldn't change directory');
                return false;
        }
}

El método getDirListing nos mostrará el contenido del directorio en uso, y para ello haremos uso de la función ftp_nlist de PHP. Esta función retorna una lista de ficheros del directorio dado. El código del método es el siguiente:

public function getDirListing($directory = '.', $parameters = '-la'){
        // obtiene el contenido del directorio
        $contentsArray = ftp_nlist($this->connectionId, $parameters . '  ' . $directory);
        return $contentsArray;
}

Para poder probarlo, en el index.php añadirmos las siguientes líneas de código:

// *** cambiamos al directorio
$ftp->changeDir($dir);

// *** Obtenemos el contenido
$contentsArray = $ftp->getDirListing();

// *** Mostramos la salida
print_r($contentsArray);

Descargando un fichero

Al igual que hicimos con la subida de archivos, lo primero que deberemos de saber es si se trata de un fichero Ascii o Binario.

Para realizar la descarga, debemos de utilizar el método ftp_get de PHP, al que se le indicará el ID de conexión, la ruta destino, ruta origen, modo.

ftp_get($this->connectionId, $fileTo, $fileFrom, $mode, 0)

El método completo es el siguiente:

public function downloadFile ($fileFrom, $fileTo){

        // *** Indicamos el modo de transferencia

        $asciiArray = array('txt', 'csv');

        $extension = end(explode('.', $fileFrom));

        if (in_array($extension, $asciiArray)) {

                $mode = FTP_ASCII;

        } else {

                $mode = FTP_BINARY;

        }



        if (ftp_get($this->connectionId, $fileTo, $fileFrom, $mode, 0)) {

                return true;

                $this->logMessage(' file "' . $fileTo . '" successfully downloaded');

        } else {

                return false;

                $this->logMessage('There was an error downloading file "' . $fileFrom . '" to "' . $fileTo . '"');

        }

}

 

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO