PHP: implementare una classe per il protocollo FTP

Short link

In questo articolo vedremo come implementare una classe wrapper di base per gestire il protocollo FTP con PHP.

Connessione

La connessione è la prima cosa da implementare. In PHP la connessione avviene in due fasi. Nella prima ci si connette all'host specificato tramite la funzione ftp_connect(). Questa funzione restituisce un handle della connessione o un errore nel caso non sia possibile connettersi all'host specificato.

L'host può essere sia un dominio che un indirizzo IP. Dopo aver stabilito la connessione, si può usare l'handle restituito per passare alla fase due, ossia il login FTP sul server che avviene tramite la funzione ftp_login(), la quale accetta come parametri l'handle della connessione, il nome utente e la password FTP.

In questa fase possiamo impostare la modalità della connessione, che può essere attiva o passiva. Ciò avviene tramite la funzione ftp_pasv() che accetta due parametri, ossia l'handle della connessione ed un valore booleano, true nel caso della modalità passiva e false nel caso della modalità attiva.

Quale modalità scegliere? Onde evitare errori, il suggerimento che si può dare è quello di optare per la modalità passiva, a meno che il server FTP remoto non sia configurato diversamente.

Il codice che rispecchia le fasi sopra elencate può essere formulato in questo modo:

class My_FTP {
    private $connectionId;

    public function __construct($host, $username, $password) {
        $this->connectionId = ftp_connect($host);
        $login = $this->login($username, $password);
    }

    private function login($username, $password) {
        $login = ftp_login($this->connectionId, $username, $password);
        ftp_pasv($this->connectionId, true);
        return $login;
    }
    //...
}

A questo punto la nostra sessione FTP è stata inizializzata e possiamo cominciare a vedere come uploadare i nostri file sul nostro spazio web, requisito fondamentale per poter effettuare la sincronizzazione dei file tra l'ambiente locale e quello remoto.

Nota di design del codice: sono state utilizzate una proprietà ed un metodo privati perché data la natura dell'operazione non è necessario che l'handle della connessione e l'operazione di login vengano esposte al di fuori della classe. Questa classe è concepita affinché una volta istanziata la sessione FTP sia già attiva.

Upload dei file

Prima di affrontare l'implementazione dell'upload dei file, occorre soffermarci un'istante sulla configurazione dei permessi di accesso dello spazio web remoto.

Per poter uplodare un file, il nostro utente FTP non solo deve avere i permessi di lettura sulla sua directory remota, ma anche, e soprattutto, permessi di scrittura.

Se per un'errata configurazione dello spazio remoto l'utente non può scrivere sulla sua directory, l'upload fallirà ed il server FTP restituirà un errore.

Come regola pratica di sviluppo, testate il servizio FTP con un client FTP e verificate che l'utente possa leggere, scrivere e scaricare ed uploadare file. A questo punto, se il test ha avuto successo, potete passare all'implementazione in PHP.

L'implementazione FTP si basa sulla funzione ftp_put() che accetta quattro parametri: l'handle della connessione, il percorso del file locale da uploadare, il percorso remoto dove uploadare il file completo del nome del file stesso ed una costante PHP che indica la modalità di caricamento, ASCII o binaria.

La modalità ASCII si applica ai file testuali (HTML, CSS, JavaScript ecc.) mentre quella binaria vale per le immagini, i documenti e così via.

A questo punto il file viene caricato ma sorge un problema: che permessi verranno assegnati a tale file? Se leggiamo la pagina di Wikipedia sui permessi accordati ai file, noteremo che un valore ottale di 0644 va bene per i file PHP ma non per i file HTML, che necessitano di permessi più ampi (0755) per poter essere resi dal web server.

Il punto è che se non impostiamo esplicitamente tali permessi, sarà il server FTP a farlo in automatico usando le sue impostazioni predefinite.

PHP ci viene in aiuto con la funzione ftp_chmod() che accetta tre parametri, ossia l'handle della connessione, il percorso remoto del file caricato e il valore numerico ottale dei permessi accordati.

Quindi possiamo scrivere:

//...
public function upload($destination_file = '', $source_file = '', $mode = FTP_ASCII, $perms = 0755) {
        $upload = ftp_put($this->connectionId, $destination_file, $source_file, $mode);
        ftp_chmod($this->connectionId, $perms, $destination_file);
        return $upload;
    }

Come regola pratica per i file locali si consiglia di utilizzare percorsi assoluti con la variabile globale $_SERVER['DOCUMENT_ROOT'] che restituisce il percorso di base della directory principale del sito locale, ma senza il / finale.

Terminare la sessione FTP

Possiamo terminare una sessione FTP usando il distruttore delle classi PHP:

public function __destruct() {
        ftp_close($this->connectionId);
    }

In questo modo quando la risorsa viene liberata la connessione FTP viene automaticamente chiusa.

L'autore

Gabriele Romanato, sviluppatore web full stack specializzato in siti, applicativi web ed e-commerce con Node.js e PHP.