1. Code
  2. PHP

Wie man mit PHP und FTP arbeitet

Scroll to top

German (Deutsch) translation by Nikol Angelowa (you can also view the original English article)

In diesem Tutorial möchten wir eine FTP-Klasse mit PHP erstellen, die gut geschrieben, nützlich und erweiterbar ist.

Umreißen Sie unser Ziel

Es ist immer wichtig, zuerst genau zu skizzieren, welche Funktionen Ihre Klasse enthalten sollte. In unserem Fall:

  • Verbindung zu einem Server herstellen
  • Erstellen Sie einen Ordner auf dem Server
  • Eine Datei hochladen
  • ändere die Richtung
  • Abrufen der Verzeichnisliste
  • Laden Sie eine Datei herunter

Wann würde ich eine FTP-Klasse verwenden?

Es gibt mehrere Fälle, in denen man diese Art von Klasse verwenden könnte. Einige Szenarien könnten sein:

  • Automatisches Hochladen von Bildern, z. B. einer Galerie, auf die Website eines Kunden (idealerweise in Verbindung mit meinem Tutorial zur Größenänderung von Bildern)
  • Führen Sie externe Sicherungen durch, indem Sie eine Datenbanksicherungsdatei von Ihrem Server auf einen anderen übertragen. (Hinweis: Dies wird für vertrauliche Informationen nicht empfohlen, da FTP kein sehr sicheres Protokoll ist.)

Hinweis: Aufgrund unterschiedlicher Serverkonfigurationen können Probleme mit FTP leicht auftreten. Dieser Code wurde erfolgreich auf mehreren FTP-Servern getestet.


Was ist FTP?

FTP: "Ein Standard-Netzwerkprotokoll zum Kopieren einer Datei von einem Host auf einen anderen."

FTP oder File Transfer Protocol ist wie von Wikipedia definiert: "Ein Standard-Netzwerkprotokoll, mit dem eine Datei über ein TCP / IP-basiertes Netzwerk wie das Internet von einem Host auf einen anderen kopiert wird."

Im Wesentlichen können Sie damit eine oder mehrere Dateien von einem Computer auf einen anderen kopieren.


Schritt 1 - Vorbereitung

Wir werden so einfach wie möglich anfangen. Erstellen Sie im Stammverzeichnis Ihres neuen Projekts zwei Dateien: index.php und ftp_class.php.

Die Datei index.php ist unsere Hauptseite, die das Objekt erstellt und die erforderlichen Methoden aufruft. Die ftp_class.php ist genau das: unsere ftp-Klasse.

Im nächsten Schritt erstellen wir das Skelett für unsere Klasse. Sobald dies geschehen ist, können Sie jedem Schritt folgen und ihn ausprobieren.


Schritt 2 - Einrichten der Klasse

Die Stärke der objektorientierten Programmierung (OOP) besteht darin, komplexem Code eine benutzerfreundliche Oberfläche zu bieten. Durch Erstellen einer Klasse - stellen Sie sich eine Klasse als Muster vor - können Sie die Daten kapseln. Dies ist einfach Jargon für einen Begriff, der sich auf das Ausblenden der Daten bezieht. Wir können diese Klasse dann immer wieder verwenden, ohne den Code neu schreiben zu müssen. Stattdessen müssen Sie nur die entsprechenden Methoden aufrufen (der Begriff "Methode" entspricht der Funktion).

Beginnen wir mit der Erstellung unserer FTP-Klasse. Öffnen Sie Ihre Datei ftp_class.php und fügen Sie den folgenden Code hinzu. Dies ist eine grundlegende Klassenskelettstruktur, die ich "FTPClient" genannt habe.

Die construct-Funktion, die als Konstruktor bezeichnet wird, ist eine spezielle Klassenmethode, die von der Klasse automatisch aufgerufen wird, wenn Sie ein neues Objekt oder eine neue Instanz der Klasse erstellen. Dies ist normalerweise ein guter Ort, um eine Initialisierung hinzuzufügen. aber für den heutigen Zweck brauchen wir es nicht. Trotzdem werden wir es hier für die zukünftige Verwendung aufbewahren.

1
	Class FTPClient
2
	{
3
		// *** Class variables

4
5
		public function __construct() {	}
6
	}

Bitte beachten Sie, dass wir für diese construct-Methode einen doppelten Unterstrich verwenden.


Schritt 3 - Klassenvariablen

Als nächstes setzen wir einige Klassenvariablen oder Eigenschaften.

1
	private $connectionId;
2
	private $loginOk = false;
3
	private $messageArray = array();

Das Präfix "private" definiert den Bereich der Variablen. In diesem Fall bedeutet dies, dass von außerhalb der Klasse nicht auf die Variable zugegriffen werden kann.

Die Variable $connectionId speichert unseren Verbindungsstrom. Die anderen beiden speichern den Status und alle Nachrichten. $loginOk ist hilfreich, um festzustellen, ob wir ordnungsgemäß verbunden sind.


Schritt 4 - Einfache Nachrichtenprotokollierung

In fast jeder Methode werden wir eine Methode namens "logMessage" aufrufen. Dies ist ein sehr grundlegender Nachrichtenhandler, mit dem wir alle von unserer Klasse erstellten Nachrichten erfassen können, um dem Benutzer Feedback zu geben.

Beachten Sie, dass wir die tatsächlichen Nachrichten nicht aus unseren Methoden return. Stattdessen geben wir true oder false zurück, je nachdem, ob eine bestimmte Operation erfolgreich war oder nicht. Dies hat seine Vorteile, gibt dem Benutzer jedoch auch keine detaillierten Informationen darüber, was gerade passiert.

Fügen Sie die folgenden zwei Methoden hinzu, damit wir feststellen können, was erfolgreich ist.

Diese Methode akzeptiert eine Variable, $message. Der Inhalt dieser Variablen wird dann dank der folgenden Zeile in unserem Klassenarray gespeichert: $this->messageArray[] = $message;

1
	private function logMessage($message) 
2
	{
3
		$this->messageArray[] = $message;
4
	}

Da $messageArray eine Klassenvariable ist, können wir über die Notation $this-> darauf zugreifen.

Innerhalb einer Klasse bezieht sich $this auf das Objekt selbst.

Um die Nachricht abzurufen, rufen wir getMessages auf.

1
	public function getMessages()
2
	{
3
		return $this->messageArray;
4
	}

Diese Methode ist eine öffentliche Methode. Wie bereits erwähnt, bezieht sich dieses private / öffentliche Geschäft lediglich auf den Umfang der Variablen oder in diesem Fall auf die Methode. Auf eine private Methode (oder Variable) kann außerhalb der Klasse nicht zugegriffen werden, während dies auf eine öffentliche Methode (oder Variable) möglich ist.

Da unsere Variable privat ist, benötigen wir eine Möglichkeit, darauf zuzugreifen. Dazu geben wir unserer Klasse eine public-Methode, auf die wir dann außerhalb der Klasse zugreifen können. Sie fragen sich vielleicht, warum wir die messageArray-Variable nicht einfach öffentlich machen können. Wir können; Das heißt, es ist einfach keine gute Praxis.

Hinweis: Im Internet gibt es zahlreiche Beispiele für vollständige Nachrichtenhandler oder Klassen, die ihnen gewidmet sind. Für dieses Tutorial arbeiten wir an einer einfachen Implementierung.


Schritt 5 - Anschließen

In diesem Schritt fügen wir die connect-Methode hinzu. Dadurch können wir eine Verbindung zu einem FTP-Server herstellen.

1
	public function connect ($server, $ftpUser, $ftpPassword, $isPassive = false)
2
	{
3
4
		// *** Set up basic connection

5
		$this->connectionId = ftp_connect($server);
6
7
		// *** Login with username and password

8
		$loginResult = ftp_login($this->connectionId, $ftpUser, $ftpPassword);
9
10
		// *** Sets passive mode on/off (default off)

11
		ftp_pasv($this->connectionId, $isPassive);
12
13
		// *** Check connection

14
		if ((!$this->connectionId) || (!$loginResult)) {
15
			$this->logMessage('FTP connection has failed!');
16
			$this->logMessage('Attempted to connect to ' . $server . ' for user ' . $ftpUser, true);
17
			return false;
18
		} else {
19
			$this->logMessage('Connected to ' . $server . ', for user ' . $ftpUser);
20
			$this->loginOk = true;
21
			return true;
22
		}
23
	}

Wir übergeben unsere Verbindungsinformationen: den Server ($server), den Benutzernamen ($ftpUser) und das Kennwort ($ftpPassword), damit wir eine Verbindung herstellen können.

Die erste Codezeile öffnet eine FTP-Verbindung mit ftp_connect zum angegebenen Server. Wir speichern unsere Verbindung zur oben beschriebenen Klassenvariablen $connectionId.

Der Code ftp_login meldet uns bei der angegebenen Verbindung an und übergibt unsere connection id, unseren Benutzernamen und unser Passwort.

Möglicherweise haben Sie die Codezeile ftp_pasv bemerkt. Dies schaltet, wie der Kommentar andeutet, den passiven Modus ein / aus. Ich würde vorschlagen, dass Sie es ausschalten. Wenn Sie jedoch Probleme beim Verbinden haben, versuchen Sie es einzuschalten. Der passive Modus kann bei der Verbindung über FTP eine Art Stute verursachen.

Wir stellen fest, ob die Verbindung erfolgreich war. Anschließend protokollieren wir die Ergebnisse, indem wir unsere einfache Message-Handler-Methode logMessage() aufrufen und die Zeichenfolge an log übergeben. Denken Sie daran: Wir verwenden $this->, um auf logMessage() zuzugreifen, da es sich um eine Klassenvariable handelt.


Schritt 6 - Aufrufen des Objekts

Jetzt, wo unsere Klasse arbeitet, können wir es ausprobieren! Öffnen Sie Ihre index.php-Datei und fügen Sie den folgenden Code hinzu.

Sie benötigen Zugriff auf einen FTP-Server, um mitspielen zu können. Wenn Sie Ihren eigenen Server einrichten möchten, probieren Sie Filezilla aus - es ist auch kostenlos.

Sie werden feststellen, dass ich hier die FTP-Serverdetails hinzugefügt habe. Idealerweise werden diese in Ihrer config-Datei gespeichert. Ändern Sie diese entsprechend den Einstellungen Ihres FTP-Servers.

Nachdem wir unsere FTP-Serverdetails definiert haben, fügen wir die Klasse mit include('ftp_class.php') ein. Dies bedeutet: Stellen Sie die Klasse auf dieser Seite zur Verfügung. In der nächsten Zeile wird ein Objekt unserer FTP-Klasse erstellt und in der Variablen $ftpObj gespeichert. $ftpObj wird jetzt verwendet, um auf alle öffentlichen Methoden in unserer Klasse zuzugreifen. Dies geschieht mit der Notation ->, genau wie in der folgenden Zeile, indem die Methode $ftpObj -> connect aufgerufen und unsere Serverdetails übergeben werden.

1
		// *** Define your host, username, and password

2
		define('FTP_HOST', '192.168.1.88');
3
		define('FTP_USER', 'Blimpf');
4
		define('FTP_PASS', 'catfish');
5
6
7
		// *** Include the class

8
		include('ftp_class.php');
9
10
		// *** Create the FTP object

11
		$ftpObj = new FTPClient();
12
13
		// *** Connect

14
		$ftpObj -> connect(FTP_HOST, FTP_USER, FTP_PASS);

Wie Sie sehen, ist die Verbindung zu unserem FTP-Server sehr einfach, sobald unsere Klasse eingerichtet ist!


Schritt 6b - Anzeigen der Ausgabe

Im letzten Schritt könnten wir den Verbindungsaufruf in eine if-Anweisung einschließen, wie unten gezeigt. Wenn wir dann keine Verbindung herstellen können, wird der abhängige Code nicht ausgeführt. Wir können dann alle Nachrichten an den Benutzer ausgeben, z. B. "verbunden" oder "fehlgeschlagen".

1
		// *** Connect

2
		if ($ftpObj -> connect(FTP_HOST, FTP_USER, FTP_PASS)) {
3
4
			// *** Then add FTP code here

5
6
			echo 'connected';
7
8
		} else {
9
			echo 'Failed to connect';
10
		}

Dies ist in Ordnung, obwohl unser Code mit IF / ELSE-Anweisungen schnell ziemlich aufgebläht wird, wenn wir dies zu allen unseren Aufrufen hinzufügen. Stattdessen möchte ich eine Alternative anbieten, die die Dinge ein bisschen sauberer und leichter zu befolgen macht.

Erinnern Sie sich an die von uns hinzugefügten Message-Handler-Methoden? Wenn Sie die von der Klasse erzeugten Nachrichten sehen möchten - hilfreich für das Debuggen / Feedback -, können Sie nach jeder von Ihnen aufgerufenen Methode den folgenden Code hinzufügen.

1
		print_r($ftpObj -> getMessages());

Dies zeigt die Klassennachricht an.


Schritt 7 - Erstellen Sie unser erstes Verzeichnis

Ausgezeichnet, jetzt ist es Zeit, etwas Nützliches zu tun. Die erste Methode, die wir erstellen werden, ist die makeDir-Methode. Wie erwartet erstellt diese Methode Verzeichnisse für uns auf dem Server. Der einzige Parameter, den wir übergeben werden, ist der Verzeichnispfad und der Ordnername. Wir nennen es $directory. Die magische Linie hier ist die integrierte Funktion ftp_mkdir. Es verwendet unsere gespeicherte "connectionId" und die übergebene $directory-Variable, um den Ordner zu erstellen.

Fügen Sie Ihrer Datei ftp_class.php den folgenden Code hinzu:

1
		public function makeDir($directory)
2
		{
3
			// *** If creating a directory is successful...

4
			if (ftp_mkdir($this->connectionId, $directory)) {
5
6
				$this->logMessage('Directory "' . $directory . '" created successfully');
7
				return true;
8
9
			} else {
10
11
				// *** ...Else, FAIL.

12
				$this->logMessage('Failed creating directory "' . $directory . '"');
13
				return false;
14
			}
15
		}

Und um es aus Ihrer index.php-Datei aufzurufen, fügen Sie Folgendes hinzu:

1
		$dir = 'photos';	
2
3
		// *** Make directory

4
		$ftpObj->makeDir($dir);

Die Variable $dir wird auf den Namen des Ordners gesetzt, den wir auf dem Server erstellen möchten. In diesem Fall: "photos".

In der nächsten Zeile wird die Methode aufgerufen, mit der der Ordner erstellt wird.

Wenn Sie den Fehler "Berechtigung verweigert" erhalten, stellen Sie sicher, dass Sie in den angegebenen Ordner schreiben können. Möglicherweise müssen Sie den Ordner in einem Verzeichnis erstellen, z. B. /httpdocs.


Schritt 8 - Hochladen einer Datei

Lassen Sie uns fortfahren und ein Foto mit dem Namen zoe.jpg hochladen. Beim Hochladen einer Datei müssen wir angeben, welchen Dateityp wir hochladen - binary oder ascii? Grundsätzlich sollten wir beim Hochladen einer Textdatei ascii verwenden. Andernfalls sollte es auf binär gesetzt werden.

Wir beginnen mit der Einrichtung eines array mit allen Erweiterungen, die wir für einen ascii-Typ-Upload verwenden sollten.

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

Dann rufen wir die Erweiterung unserer Datei ab, damit wir testen können, ob es sich um einen der ascii-Typen handelt. Wir ermitteln dies, indem wir die Erweiterung der Datei abrufen, die wir hochladen. Die schnelle und schmutzige Methode, die ich hier verwendet habe, ist durch "Explodieren" der Datei mit dem '.' als Begrenzer. Dadurch wird die Datei in Teile aufgeteilt und als array gespeichert. Mit einer anderen integrierten PHP-Funktion, "end", wählen wir das letzte array-Element aus, das unsere Erweiterung enthält. Es ist ein ordentliches kleines Stück Code.

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

Als nächstes testen wir, ob unsere Erweiterung in der Liste (mit in_array) der Dateierweiterungen angezeigt wird, die als Typ ascii hochgeladen werden sollen. Wenn es in der Liste erscheint, setzen wir die Variable $mode auf FTP_ASCII; Andernfalls nehmen wir an, dass es sich um einen Binärtyp handelt, und weisen $mode den Wert FTP_BINARY zu.

1
in_array($extension, $asciiArray)

ftp_put lädt eine Datei von Ihrem lokalen Speicherort in eine entfernte Datei auf dem FTP-Server hoch. Wir übergeben ihm unsere "connectionId", den Pfad zu der Datei, in die wir hochladen möchten ($fileTo), den Pfad der Datei, die wir hochladen möchten ($fileFrom), und des Modus ($mode), den wir gerade bestimmt haben.

Fügen Sie als Nächstes die folgende Methode zu Ihrer Datei ftp_class.php hinzu:

1
	public function uploadFile ($fileFrom, $fileTo)
2
	{
3
		// *** Set the transfer mode

4
		$asciiArray = array('txt', 'csv');
5
		$extension = end(explode('.', $fileFrom));
6
		if (in_array($extension, $asciiArray)) {
7
			$mode = FTP_ASCII;		
8
		} else {
9
			$mode = FTP_BINARY;
10
		}
11
12
		// *** Upload the file

13
		$upload = ftp_put($this->connectionId, $fileTo, $fileFrom, $mode);
14
15
		// *** Check upload status

16
		if (!$upload) {
17
18
				$this->logMessage('FTP upload has failed!');
19
				return false;
20
21
			} else {
22
				$this->logMessage('Uploaded "' . $fileFrom . '" as "' . $fileTo);
23
				return true;
24
			}
25
	}

Natürlich können Sie jeden gewünschten Ordnernamen erstellen oder hochladen! Fügen Sie diesen nächsten Codeausschnitt zu Ihrer index.php-Datei hinzu und passen Sie ihn entsprechend an.

1
		$fileFrom = 'zoe.jpg';				
2
		$fileTo = $dir . '/' . $fileFrom;
3
		
4
		// *** Upload local file to new directory on server

5
		$ftpObj -> uploadFile($fileFrom, $fileTo);

Inzwischen sollten Sie sich damit abfinden, wie einfach diese Klasse zu bedienen ist! Wir führen nur einzelne Anrufe durch, um unsere Aufgaben auszuführen - alles dank objektorientierter Programmierung!


Schritt 9 - Anzeigen der Dateien

Lassen Sie uns nun bestätigen, dass sich unsere Datei im photo ordner befindet. Wir können dies tun, indem wir zum Ordner "photo" auf unserem Server navigieren und dann den Inhalt anzeigen.

Die changeDir-Methode verwendet "ftp_chdir", um das aktuelle Verzeichnis auf dem FTP-Server zu ändern. Übergeben Sie einfach das Verzeichnis, in das Sie wechseln möchten. Einfach und süß.

ftp_class.php:

1
	public function changeDir($directory)
2
	{
3
		if (ftp_chdir($this->connectionId, $directory)) {
4
			$this->logMessage('Current directory is now: ' . ftp_pwd($this->connectionId));
5
			return true;
6
		} else { 
7
			$this->logMessage('Couldn\'t change directory');
8
			return false;
9
		}
10
	}

getDirListing zeigt den Inhalt des Verzeichnisses an, in dem Sie sich befinden, indem Sie die Funktion "ftp_nlist" verwenden. Diese Funktion gibt eine Liste der Dateien in einem bestimmten Verzeichnis zurück. Das aktuelle Verzeichnis ist standardmäßig festgelegt, sodass Sie keine Parameter angeben müssen.

Wenn Sie möchten, können Sie dies überschreiben, indem Sie den $directory-Pfad übergeben, dessen Inhalt Sie anzeigen möchten. Die Variable $parameters ist standardmäßig '-la'. Dies ist ein Linux-Befehl, um weitere Informationen zum Verzeichnis anzuzeigen. Fühlen Sie sich frei, es zu entfernen oder eine leere Zeichenfolge einzugeben.

ftp_class.php:
1
	public function getDirListing($directory = '.', $parameters = '-la')
2
	{
3
		// get contents of the current directory

4
		$contentsArray = ftp_nlist($this->connectionId, $parameters . '  ' . $directory);
5
6
		return $contentsArray;
7
	}

Die Methode getDirListing gibt ein array zurück, das unsere Verzeichnisliste enthält.

index.php
1
		// *** Change to folder

2
		$ftpObj->changeDir($dir);
3
4
		// *** Get folder contents

5
		$contentsArray = $ftpObj->getDirListing();
6
7
		// *** Output our array of folder contents

8
		echo '<pre>';
9
		print_r($contentsArray);
10
		echo '

';

Ihr Ergebnis sollte folgendermaßen aussehen:


Schritt 10 - Herunterladen einer Datei

Während wir uns dem Abschluss dieses Tutorials nähern, fahren wir als nächstes mit dem Herunterladen der Datei fort. Die Methode beginnt mit demselben Code wie uploadFile, indem sie bestimmt, ob die Datei, die wir herunterladen möchten, ascii oder binary ist.

Bei dieser Methode übergeben Sie einfach den Dateinamen (und möglicherweise den Pfad, je nachdem, ob Sie sich im selben Ordner wie die Datei befinden, die Sie herunterladen möchten) der herunterzuladenden Datei und den Namen, den diese Datei haben soll Ihr Client-Computer.

Um eine Datei herunterzuladen, müssen Sie ftp_get aufrufen.

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

Dadurch wird eine Datei von einem Remote-Server auf unseren lokalen Computer heruntergeladen. Es akzeptiert den folgenden Parameter: Unsere Verbindungs-ID, den Pfad und den Dateinamen, die lokal gespeichert werden sollen (werden überschrieben, wenn dies der Fall ist existiert bereits) ($fileTo), den Speicherort und den Namen der Datei auf dem Remote-Server ($fileFrom) und den Modus ($mode).

ftp_class.php
1
	public function downloadFile ($fileFrom, $fileTo)
2
	{
3
4
		// *** Set the transfer mode

5
		$asciiArray = array('txt', 'csv');
6
		$extension = end(explode('.', $fileFrom));
7
		if (in_array($extension, $asciiArray)) {
8
			$mode = FTP_ASCII;		
9
		} else {
10
			$mode = FTP_BINARY;
11
		}
12
13
		// try to download $remote_file and save it to $handle

14
		if (ftp_get($this->connectionId, $fileTo, $fileFrom, $mode, 0)) {
15
16
			return true;
17
			$this->logMessage(' file "' . $fileTo . '" successfully downloaded');
18
		} else {
19
20
			return false;
21
			$this->logMessage('There was an error downloading file "' . $fileFrom . '" to "' . $fileTo . '"');
22
		}
23
24
	}

Wir werden dieselbe Datei herunterladen, die wir hochgeladen haben, indem wir sie unter einem anderen Namen auf unserem Client-Computer speichern.

Hinweis: Stellen Sie erneut sicher, dass Ihre Berechtigungen korrekt eingestellt sind!

Da wir uns jetzt in unserem photo-Ordner befinden sollten, fügen wir der Variablen $fileFrom keinen Pfad hinzu, sondern nur den Dateinamen.

index.php
1
		$fileFrom = 'zoe.jpg';		# The location on the server

2
		$fileTo = 'zoe-new.jpg';			# Local dir to save to

3
4
		// *** Download file

5
		$ftpObj->downloadFile($fileFrom, $fileTo);

Schritt 11 - Fertig stellen

Um unsere Klasse zu vervollständigen, fügen wir die Klassenmagiemethode __deconstruct hinzu. Diese Methode schließt unsere Verbindung, wenn der Verweis auf unser Objekt nicht mehr vorhanden ist - möglicherweise wurde die Seite geschlossen. In jedem Fall wird dieser Code ausgeführt und die Verbindung geschlossen. Es ist immer eine gute Praxis, dies einzubeziehen, obwohl dies nicht unbedingt erforderlich ist.

1
	public function __deconstruct()
2
	{
3
		if ($this->connectionId) {
4
			ftp_close($this->connectionId);
5
		}
6
	}

Abschluss

Nun das macht es! Ich hoffe, Sie haben jetzt ein besseres Verständnis für die Verwendung von FTP mit PHP. Sie sollten nun über die erforderlichen Fähigkeiten verfügen, um diese Klasse weiter zu erweitern und andere allgemeine Aufgaben zu unterstützen, z. B. das Umbenennen oder Löschen von Dateien und Ordnern.

Teilen Sie uns unbedingt mit, wenn Sie coole PHP-FTP-Clients erstellen!