phpBuddy

Folge phpBuddy.eu auf Twitter

Ab sofort können alle Twitter-Begeisterte sich auch über die Aktivitäten von phpBuddy.eu auf Twitter informieren. Ich werde dort in unregelmäßigen Abständen über neue Artikel, Tutorials, Kurztipps, lesenswerte Forumeinträge oder schlicht interessante PHP Funktionen informieren.

Sie sind hier: Startseite FTP Klasse
FTP Klasse

Hallo,

letztens benötigte ich FTP-Funktionalität für ein Script und musste ernüchtert feststellen, dass PHP selbst nur umständliche (und teilweise unlogische) Funktionen für eine prozedurale Verwendung bereitstellt. Nach ausgedehnten Google-Sessions habe ich auch nur FTP Klassen gefunden die entweder total sch...lecht programmiert waren, oder einfach nicht das boten was ich gesucht habe. Also habe ich mich mal dran gesetzt und mir selbst eine FTP Klasse geschrieben. Für den Fall das sie der ein oder andere vielleicht irgendwann mal brauchen könnte, stelle ich sie hier zur Verfügung.

Die folgenden Anwendungsbeispiele stellen nur einen Bruchteil der Möglichkeiten vor. Insgesamt ist die Klasse (ohne Exception Klasse) knapp 960 Zeilen lang und umfaßt über 30 Methoden. Wer sich einen genauen Überblick verschaffen möchte sollte den Quelltext durchgehen oder mit phpDocumentor eine Doku generieren lassen, da die Klasse voll durchkommentiert ist.

Die Klasse setzt PHP 5.2.2 oder höher voraus!

Anwendungsbeispiele:

<?php
 
header( 'Content-Type: text/html; charset=utf-8' );
error_reporting( 0 );
 
// Zugangsdaten als Array
$config = array( "host"     => "ftp.domain.tld",
                 "username" => "fritzchen",
                 "password" => "1234",
                 "port"     => 21 );
 
// Klassen automatisch nachladen
function __autoload( $klasse )
{
    if (file_exists( strtolower( $klasse ). '.class.php' ))
    {
        include_once( strtolower( $klasse ). '.class.php' );
    }
}
 
 
/* ************************************************* */
/* ***   A n w e n d u n g s b e i s p i e l e   *** */
/* ************************************************* */
 
try
{
    /**
     * getInstance() - Statische Methode zum instanzieren der Klasse
     */ 
    $ftp = FTP::getInstance();
 
    /**
     * connect - verbindet zum FTP, meldet einen Benutzer an, setzt Passiven Modus, ermittelt Server OS
     *
     * Parameter:
     * $config Array mit Zugangsdaten
     * true    Sichere SSL Verbindung benutzen
     * true    Falls der Server kein FTPS unterstützt, normale Verbindung als Fallback benutzen
     *
     * Wird als 3. Parameter false angegeben wird ein Fehler geworfen, falls FTPS fehlschlägt.
     */ 
    $ftp->connect( $config, true, true );
}
catch (FTPException $error)
{
    echo $error->getMessage();
}
 
 
/**
 * changeDir - Wechselt das Arbeitsverzeichnis
 *
 * Parameter:
 * string  Pfad zum Verzeichnis in das gewechselt werden soll
 */ 
$ftp->changeDir( '/pfad/zum/verzeichnis' );
 
 
/**
 * getDir - Gibt den Name des Arbeitsverzeichnisses aus
 */ 
echo $ftp->getDir();
 
 
/**
 * getSimpleFileList - Gibt Verzeichnis- und Dateinamen eines Verzeichnis aus
 *
 * Parameter:
 * string  Falls ein Pfad angegeben wird, wird dieser Verzeichnisinhalt ermittelt. Ohne Parameter wird das aktuelle Arbeitsverzeichnis ausgelesen, das mit changeDir() gesetzt wurde.
 */ 
$liste = $ftp->getSimpleFileList();
foreach ($liste as $file)
{
    if ($file != '.' && $file != '..')
    {
        echo $file. "\n";
    }
}
 
 
/**
 * getFileList - Gibt den Inhalt eines Verzeichnis aus
 *
 * Parameter:
 * string  Pfad zum Verzeichnis das ausgelesen werden soll
 * integer 0 = einfache Liste als Array. 1 = Liste als mehrdimensionales Array mit erweiterten Informationen
 */ 
$liste = $ftp->getFileList( '/pfad/zum/verzeichnis', 1 );
foreach ($liste as $dir => $file)
{
    // Gibt nur Dateien aus, keine Verzeichnisse
    if ($liste[$dir]['type'] == 'File')
    {
        echo $liste[$dir]['name']. "\n";
        echo $liste[$dir]['chmod']. "\n";
        echo $liste[$dir]['size']. "\n";
        echo $liste[$dir]['modified']. "\n";
        echo $liste[$dir]['owner']. "\n";
        echo $liste[$dir]['group']. "\n";
        echo $liste[$dir]['day']. "\n";
        echo $liste[$dir]['month']. "\n";
    }
}
 
/**
 * getFileListRecursive - Gibt den Inhalt eines Verzeichnisbaums aus
 *
 * Parameter:
 * string  Pfad zum Verzeichnis das ausgelesen werden soll
 * integer 0 = einfache Liste als Array. 1 = Liste als mehrdimensionales Array mit erweiterten Informationen
 * integer 0 = void. 1 = Rückgabewert ist ein Array mit alles Verzeichnisnamen inklusive Pfad
 */ 
$liste = $ftp->getFileListRecursive( '/pfad/zum/verzeichnis', 1, 1 );
foreach ($liste as $dir => $file)
{
    // Wie im vorherigen Beispiel
}
 
 
/**
 * chmod - Ändert Dateirechte
 *
 * Parameter:
 * string  Dateiname der zu modifizierenden Datei
 * integer CHMOD als Oktalzahl
 */ 
$ftp->chmod( '/pad/zur/datei.html', 0766 );
 
 
/**
 * rename - Ändert Dateiname
 *
 * Parameter:
 * string  Alter Name
 * string  Neuer Name
 */ 
$ftp->rename( 'alter_name.html', 'neuer_name.html' );
 
 
/**
 * delete - Löscht Datei
 *
 * Parameter:
 * string  Dateiname
 */ 
$ftp->delete( '/pfad/zur/loesch_mich.html' );
 
 
/**
 * removeDir - Löscht ein Verzeichnis oder eine Verzeichnisstruktur rekursive
 *
 * Parameter:
 * string  Pfad zum Verzeichnis das gelöscht werden soll
 * integer 0 = void. 1 = Löscht rekursive alle Dateien und Verzeichnisse in diesem Verzeichnis.
 * ACHTUNG: Diese Methode sollte nur mit äußerster Vorsicht benutzt werden, da ohne Warnung wirklich alles in dem Verzeichnis gelöscht wird!
 */ 
$ftp->removeDir( '/pfad/zum/verzeichnis', 1 );
 
 
/**
 * makeDir - Erstellt ein Verzeichnis oder eine komplette Verzeichnisstruktur
 *
 * Parameter:
 * string  Verzeichnisname oder Struktur die zu erstellen ist
 * integer 0 = void. 1 = Rekursive Erstellung der Verzeichnisstruktur
 */ 
$ftp->makeDir( '/neue/verzeichnis/struktur', 1 );
 
 
/**
 * upload - Kopiert eine Datei vom lokalen Filesystem auf einen FTP
 *
 * Parameter:
 * string  Pfad und Name der Datei auf dem lokalen System
 * string  Pfad und Name wo die Datei hinkopiert werden soll
 * string  Übertragungsmodus: 'ascii' = ASCII Modus, 'binary' = Binär Modus, 'auto' = Anhand einer Dateiendungenliste wird versucht automatisch den richtigen Modus zu ermitteln
 * integer Position (Pointer) von/ab der die Übertragung aufgenommen werden soll
 */ 
$ftp->upload( 'lokale_datei.zip', 'datei_auf_ftp.zip', 'auto', 0 );
 
 
/**
 * download - Kopiert eine Datei vom FTP auf das lokale Filesystem
 *
 * Parameter:
 * string  Pfad und Name auf dem FTP Server
 * string  Pfad und Name wo die Datei lokal hinkopiert werden soll
 * string  Übertragungsmodus: 'ascii' = ASCII Modus, 'binary' = Binär Modus, 'auto' = Anhand einer Dateiendungenliste wird versucht automatisch den richtigen Modus zu ermitteln
 * integer Position (Pointer) von/ab der die Übertragung aufgenommen werden soll
 */ 
$ftp->download( 'datei_auf_ftp.zip', 'lokale_datei.zip', 'auto', 0 );
 
?>

Codebeispiel aus der FTP Klasse:

    /**
     * Connect to the FTP server.
     * Also sends login information, detects target FTP OS and sets Passive Mode to TRUE
     *
     * @param  array  $config Login information to connect at the FTP server
     * @param  bool   $useSSL Establish a secure SSL-FTP connection
     * @param  bool   $fallback If a SSL-FTP connect fails, try a default FTP connect as fallback 
     * @return void
     */
    public function connect( $config=array(), $useSSL=false, $fallback=false )
    {
        // Check if native FTP support is enabled
        if (function_exists( 'ftp_connect' ) === false)
        {
            throw new FTPException( FTPException::FTP_SUPPORT_ERROR );
        }
 
        // Default connection
        if ($useSSL === false)
        {
            if (!$this->cid = @ftp_connect( $config['host'], $config['port'] ))
            {
                throw new FTPException( FTPException::CONNECT_FAILED_BADHOST );
            }
        }
 
        // SSL-FTP connection
        if ($useSSL === true)
        {
            if (!function_exists( 'ftp_ssl_connect' ) ||
                !$this->cid = @ftp_ssl_connect( $config['host'], $config['port'] ))
            {
                if ($fallback === false)
                {
                    throw new FTPException( FTPException::CONNECT_FAILED_NOSSL );
                }
                // Default connection as fallback
                else if ($fallback === true)
                {
                    if (!$this->cid = @ftp_connect( $config['host'], $config['port'] ))
                    {
                        throw new FTPException( FTPException::CONNECT_FAILED_BADHOST );
                    }
                }
            }
        }
 
        // Send login information
        if (@ftp_login( $this->cid, $config['username'], $config['password'] ) === false)
        {
            throw new FTPException( FTPException::CONNECT_FAILED_BADLOGIN );
        }
 
        // Detect FTP Server OS
        // This is required by some operations, such as chmod, to prevent wrong return values
        $tmpOS = strtoupper( self::getSystem() );
        if (strpos( $tmpOS, 'MAC' ) !== false)
        {
            $this->serverOS = 'MAC';
        }
        else if (strpos( $tmpOS, 'WIN' ) !== false)
        {
            $this->serverOS = 'WIN';
        }
        else if (strpos( $tmpOS, 'UNIX' ) !== false)
        {
            $this->serverOS = 'UNIX';
        }
        else
        {
            throw new FTPException( FTPException::CONNECT_UNKNOWN_OS );
        }
 
        // Set Passive mode
        self::setPassiveMode( true );
    }
 
 
    /**
     * Converts a simple file list array into a multidimensional array
     * File size in Byte is converted with convertSize( size )
     * Symbolic CHMOD is converted to octal with convertToOctal( chmod )
     *
     * @param  array  $rawfilelist Array with file list
     * @return array  File list
     */
    protected function extractFileInfo( $rawfilelist )
    {
        $filearray = array();
        if (is_array( $rawfilelist ))
        {
            foreach ($rawfilelist as $rawfile)
            {
                $fileinfo = preg_split( "/[\s]+/", $rawfile );
                if ($fileinfo[8] != '.' &&
                    $fileinfo[8] != '..')
                {
                    switch ($fileinfo[0]{0})
                    {
                        case '-': $file['type'] = 'File'; break;
                        case 'd': $file['type'] = 'Dir'; break;
                        case 'l': $file['type'] = 'Link'; break;
                        default : $file['type'] = 'File'; break;
                    }
                    $file['chmod']    = self::convertToOctal( $fileinfo[0] );
                    $file['hardlink'] = $fileinfo[1];
                    $file['owner']    = $fileinfo[2];
                    $file['group']    = $fileinfo[3];
                    $file['size']     = self::convertSize( $fileinfo[4] );
                    $file['month']    = $fileinfo[5];
                    $file['day']      = $fileinfo[6];
                    $file['modified'] = $fileinfo[7];
                    $file['name']     = $fileinfo[8];
                    $filearray[$file['name']] = $file;
                }
            }
        }
        return $filearray;
    }
 
 
    /**
     * Set the transfer mode for uploads/downloads
     *
     * @param  string   $mode Transfer mode (ascii | binary | auto)
     * @return integer  1 = ASCII | 2 = BINARY
     */
    protected function transferMode( $mode )
    {
        // Check if a correct mode is given
        if ($mode != 'ascii' || $mode != 'binary' || $mode != 'auto')
        {
            $mode = 'auto';
        }
        // Try to determine the transfer mode by file extension
        if ($mode == 'auto')
        {
            $ext = array_pop( explode( '.', $remotefile ) );
            $transfermode = in_array( $ext, $this->ascii_array ) ? FTP_ASCII : FTP_BINARY;
        }
        // Force transfer mode by user
        else if ($mode == 'ascii')
        {
            $transfermode = FTP_ASCII;
        }
        else if ($mode == 'binary')
        {
            $transfermode = FTP_BINARY;
        }
        return $transfermode;
    }

Wer Fehler findet oder Verbesserungsvorschläge hat kann mir diese gerne mitteilen.

Viel Spaß mit der Klasse,
Andreas

FTP Klasse (9 KB)