Pixelwerker - Werbeagentur in Kassel

Zugriff auf FTP Storage über Laravel 5.6

Der Zugriff auf einen FTP Server, sowie auf viele andere Speicherorte ist eine gängige Aufgabe in der Programmierung. Das PHP Framework Laravel bietet für den Zugriff auf viele unterschiedliche Speicherorte eine generische Zugriffsmethode. Amazons S3, der lokale Server-Speicher, FTP Server, etc. werden als disks behandelt. Laravel bietet diese Funktion dank des PHP Pakets Flysystem von  Frank d...

Der Zugriff auf einen FTP Server, sowie auf viele andere Speicherorte ist eine gängige Aufgabe in der Programmierung. Das PHP Framework Laravel bietet für den Zugriff auf viele unterschiedliche Speicherorte eine generische Zugriffsmethode. Amazons S3, der lokale Server-Speicher, FTP Server, etc. werden als disks behandelt. Laravel bietet diese Funktion dank des PHP Pakets Flysystem von  Frank de Jonge an. Detailliertere Informationen zu allen Speichermethoden findet Ihr wie immer in der Dokumentation von Laravel.

In diesem Artikel betrachten wir das Szenario, dass es einen täglichen CSV Export in ein Verzeichnis eines FTP Servers gibt. Die Plattform soll diese Datei dann mit einem nächtlich geplanten Task vom FTP Server laden, überprüfen, ob die Datei bereits importiert wurde und wenn dies nicht der Fall ist, die Datei über die Task Queue importieren. Ich habe auch einen interessanten Artikel über die Laravel Task Queue und einen damit verbundenen CSV Import geschrieben, der für Dich ebenfalls interessant sein könnte.

Ich gehe in diesem Artikel nicht auf die Einrichtung eines kompletten Laravel Projektes ein. Eine gute Anleitung dazu findest Du ebenfalls in der Laravel Dokumentation zur Projekterstellung.

FTP Filesystem Konfiguration

Damit Du FTP als disk benutzen kannst, ist es zunächst wichtig Änderungen an der Konfigurationsdatei „config/filesystems.php“ vorzunehmen. Der Array-Knoten „disks“  muss dazu um folgenden Block „ftp“ erweitert werden:


Du kannst nun die Zugangsdaten zum FTP Server in den Feldern „host“, „username“ und „password“ hinterlegen. Entweder trägst Du diese direkt ein, oder Du hinterlegst diese in der „.env“ Datei Deines Projektes und lädst die Daten wie im Knoten „s3“ über die „env()“ Funktion. Dies hat den Vorteil, dass Du je nach Umgebung andere Daten hinterlegen kannst, ohne jedesmal Änderungen am Quellcode durchführen zu müssen. Hier findest nochmal ein Beispiel mit env Variablen:


In der „.env“ Datei musst Du diese Variablen jetzt natürlich auch noch hinterlegen. Füge diese am Ende (oder einer von Dir favorisierten Stelle) der Datei ein:


Um später den Import-Pfad dynamisch anpassen zu können, hinterlege ich auch diesen als Environment Variable. Nun legen wir noch eine eigene Konfigurationsdatei an, deren Werte wir zum späteren Zeitpunkt mit der „config“ Helper-Funktion auslesen können. Infos zu dieser Funktion findest Du im Abschnitt Helper Dokumentation von Laravel. Erstelle nun die Datei „ftpcsvimport.php“ im Verzeichnis „config“ mit folgendem Inhalt:


Neben der Konfiguration für das Import-Verzeichnis wurden auch die Konfigurationen für den CSV Import bereits hinterlegt. An dieser Stelle musst Du Deine benötigten CSV Spalten-Header und Deine Pflichtspalten, also Spalten die über Inhalte verfügen müssen, hinterlegen. Ich verwende lediglich Beispieldaten zu Anschauungszwecken.

Damit Deine durchgeführte Konfiguration wirksam wird, musst Du zunächst den Laravel Cache neu befüllen. Das kannst Du ganz leicht über den folgenden Konsolenbefehl:

Erstellung des CSV-Import Jobs

Die Konfiguration der disks ist abgeschlossen, aber wie bekommen wir nun unsere CSV Datei vom FTP Server? Wir müssen zunächst ein neues Eloquent Model samt Migration anlegen, um bereits importierte Dateien auszuschließen. Dazu führst Du folgenden Befehl im Terminal aus:


Dieser Befehl legt das neue Model „ImportedFile“ im Ordner „app/ImportedFile.php“ an. Durch das „-m“ wird eine passende Datenbankmigration für die neue Tabelle „imported_files“ im Ordner „database/migrations“ angelegt. Der Name der Datei sollte folgendem Aufbau besitzen „2018_07_16_093346_create_imported_files_table.php“. Selbstverständlich ist bei Dir der Zeitpunkt vor „create_imported_files_table.php“ ein anderer als bei mir.

Öffne nun die Migrationsdatei und passe den Inhalt von Schema::create in der Funktion „up“ folgendermaßen an:


Durch den „unique“ Index muss der Dateiname der Importierten Datei eindeutig und einzigartig sein, und darf nicht nochmals importiert werden. Diese Property muss nun auch noch im Model implementiert werden. Dazu öffnest Du die Datei „app/ImportedFile.php“ und fügst folgenden Inhalt ein:


Zum Schluss musst Du die Migration noch durchführen, damit die Änderungen per „code first“ in die Datenbank übertragen werden. Verwende dazu folgenden Befehl in der Konsole (Vergiss aber nicht zuvor die Datenbank Verbindungsvariablen in der .env Datei korrekt zu befüllen):


Jetzt können wir mit der Erstellung des Jobs fortfahren. Der Job wird später automatisch zu einem geplanten Zeitpunkt (task scheduling) „gequeued“ und von einem freien konfigurierten Queue-Worker ausgeführt. Um einen Job anzulegen führst Du folgenden Befehl aus:


Im Verzeichnis „app/Jobs“ wurde nun die Job Datei „ImportCsvFromFtpServer.php“ angelegt. Der CSV Import im Job wird später über das PHP Paket league/csv in der Version 9.0 durchgeführt. Dieses kannst Du über den PHP Abhängigkeitsmanager Composer mit folgendem Befehl installieren:


Es steht Dir natürlich frei, ein anderes PHP Paket, oder zu einem späteren Zeitpunk eine aktuellere Version von league/csv zum Import zu verwenden, oder den Import bspw. über die PHP Funktion str_getcsv selbst zu implementieren. Ich habe mit dem Paket von thephpleague bisher gute Erfahrungen gemacht, da der Implementierungsaufwand um ein vielfaches geringer ist. Das zahlt sich nicht nur für Dich aus, sondern auch für Projektkosten Deines Kunden. Durch den „autoload“ Knoten in der „league/csv“ composer.json musst Du das Paket nicht in Deiner „app.php“ Konfiguration hinterlegen.

Im Import Job ImportCsvFromFtpServer erstellst Du nun zunächst die privaten Properties für das Import Verzeichnis und den CSV Import und befüllst sie im Konstruktor:


Nachdem im Konstruktor das Import-Verzeichnis und die Import-Konfigurationen ermittelt wurden, können wir uns mit dem Import beschäftigen. Aber wie importieren wir nun alle bisher nicht importierten Dateien? Um zu überprüfen, welche Dateien noch nicht importiert wurden, müssen wir erst einmal alle Dateinamen aus dem Import-Verzeichnis ermitteln. Dazu können wir auf unserer FTP disk die Methode „files“ verwenden, der wir einen Verzeichnispfad übergeben und zwar den, den wir in der Environment Variable hinterlegt haben.

Danach werden alle Dateinamen der mit einer Schleife durchlaufen und es wird für jeden Dateinamen überprüft, ob er in der Datenbank existiert. Ist das nicht der Fall, so können wir ihn in eine Liste mit nicht importierten Dateien aufnehmen, die zuletzt geladen und importiert werden. In der Praxis sieht das nun folgendermaßen aus:


Am Ende der Funktion „handle“ wird die Funktion „importFiles“ aufgerufen. Diese ist zuständig für das Abarbeiten der Liste aller zu importierenden Dateien. Des weiteren beinhaltet sie die Verwaltung der Datenbank-Transaktion und das Error-Logging:


Sollte während des Imports ein Fehler auftreten, so wird ein Rollback der Transaktion durchgeführt und die importierten Daten wieder entfernt. Nach dem Rollback erfolgt das Logging  mit dem konfigurierten Treiber.

Innerhalb der Schleife wird geprüft, ob die aktuelle Datei im Dateisystem existiert. Ist das der Fall, dann wird der Dateiname an die Funktion „importFile“ übergeben, die dann mittels league/csv den CSV Import in die Datenbank durchführt. Wurde die Datei erfolgreich importiert, so gibt die Funktion ein „true“ zurück und es wird ein neuer Eintrag in der Tabelle „imported_files“ hinzugefügt.

Zu guter Letzt müssen wir nun noch die Funktion „importFile“ implementieren. Diese benötigt noch einige Helfer-Funktionen die wir zuvor noch im Job integrieren. Die folgenden Funktionen überprüfen, ob die benötigten Spalten-Header in der CSV-Datei existieren und ob die benötigten Spalten mit Inhalten gefüllt sind. Zuletzt folgt noch eine Funktion zur einfachen Ermittlung eines Array Wertes.


Die Import Funktion ist sehr komplex und kann auch noch weiter refaktorisiert und aufgespalten werden. Die einzelnen Abschnitte der Funktion werden im Nachhinein erklärt. Wichtig ist, dass Du genau wie in der „ftpcsvimport.php“ Dein Model integrierst, das importiert werden soll. Im Beispiel ist das Model „Data“ symbolisch für Dein Model hinterlegt. Das Beispiel dient lediglich als Implementierungsgrundlage und muss von Dir angepasst werden.


Im ersten Abschnitt der Funktion werden die Inhalte der zu importierenden Datei vom FTP Server als Zeichenkette geladen. Über den League Reader werden diese danach mit den CSV Einstellungen, wie bspw. dem Trennzeichen, als ResultSet geladen:


Das ResultSet wird im Anschluss überprüft. Es sollte die benötigten Header, sowie einen Inhalt besitzen:


Nachdem sichergestellt wurde, dass die Datei über die Header, sowie über Inhalt verfügt, beginnt der Import der einzelnen Datensätze der Datei. Mit einer Schleife werden alle Reihen des „Generator“ durchlaufen, sichergestellt, dass die benötigten Spalten über Inhalte verfügen und zuletzt das Model in der Datenbank erstellt:


Am Ende der Funktion befindet sich noch ein wenig Error-Handling das beliebig von Dir verfeinert und erweitert werden kann.

Task Scheduling implementieren

Die Planung von Aufgaben erfolgt in der Datei „Kernel.php“. Diese befindet sich im Verzeichnis „app/Console/“. In der Funktion „schedule“ wird unser zuvor erstellter Job nun implementiert:


Wird „schedule“ nun Aufgerufen, so wird unser Job „geplant“ und täglich um „0:00“ in die Task-Queue „eingereiht“. Aber woher kommt nun die Queue und wie ruft Laravel automatisch um Mitternacht das „einreihen“ in die Task-Queue auf? Welche Queue Du verwendest ist zunächst Dir überlassen. Es gibt viele unterschiedliche Anbieter einer Task-Queue. Detailliertere Informationen zur Einrichtung einer Queue kannst Du der Dokumentation zu Queues entnehmen. Auf der Server-Management Plattform Laravel Forge lassen sich sehr einfach produktive Laravel-Umgebungen auf dem Cloud-Server Anbieter Deiner Wahl einrichten. Deine Queues können im Backend einfach angelegt und konfiguriert werden.

Das selbe gilt für die Ausführung Deiner geplanten Tasks. Dazu ist es nötig, dass Du einen Cron-Job auf Deinem Server einrichtest. Wenn Du Dich nicht mit der Einrichtung von Cron-Jobs auskennst, ist die Verwendung eines von Laravel Forge konfigurierten Webservers für Dich die beste Wahl. Dort kannst Du im Backend einfach konfigurieren, wann „schedule“ ausgeführt werden soll. Alternativ kannst Du selbstverständlich selber Cron-Jobs anlegen. Hierzu rufst Du in der Konsole die Cron-Job Verwaltung „crontab“ auf:


Hier kannst Du nun Deine Cron-Jobs des Servers hinterlegen. Über den folgend Eintrag wird der „scheduler“ jede Minute einmal „schedule“ aufrufen. Sollte der dort konfigurierte Zeitpunkt erreicht sein, wird bspw. der Import Job gequeued.

Fazit

In diesem Artikel habe ich Dir gezeigt, wie Du in Deiner Laravel-Anwendung einen automatischen CSV-Import von einem FTP Server implementierst. Ich hoffe, dass er Dir weiterhelfen konnte. Solltest Du Fragen haben, oder ich etwas wichtiges Vergessen habe, was Dir weiterhelfen könnte, lass mir doch einen Kommentar da und ich versuche Dir weiterzuhelfen.

Durch unsere langjährige Arbeit und über 100 erfolgreiche Projekte, konnten wir viele Erfahrungen sammeln. Dieses Know-How im Online-Marketing gaben wir u.a. bei Vorträgen von Google, der Industrie- und Handelskammer und der Handwerkskammer weiter.

Mit Know-How, Kreativität und Leidenschaft entwickeln wir auf unsere Kunden abgestimmte Marketing-Strategien, die Sie sicher und nachhaltig zum Erfolg führen. Gemeinsam setzen wir Ihr Online-Marketing so um, dass Sie langfristig Ihren Umsatz und Return-On-Investment steigern.

Jetzt kostenlosen Beratungstermin vereinbaren   oder unter 0561 / 850 194 76 anrufen.

Bewertung:
Bewertungen: 179 Ihre Bewertung: {{rating}}

Weitere interessante Artikel

Schreibe einen Kommentar:

Vereinbaren Sie jetzt Ihre
unverbindliche Erstberatung

Rufen Sie jetzt an & vereinbaren
Sie Ihren persönlichen Termin!

0561 - 850 194 76
Jetzt Kontakt aufnehmen!
Britta Schwab
Britta Schwab

Agenturleitung & Marketing-Rockstar

"Ich freue mich darauf Sie und Ihr Projekt bei einer Tasse Kaffee kennenzulernen".

Oder schreiben Sie uns jetzt eine Nachricht:

Geben Sie Ihre E-Mail-Adresse an, unter der wir Sie kontaktieren können.

Sagen Sie uns worum es geht und für welche Themen Sie sich interessieren.

Wir benutzen Cookies um die Nutzerfreundlichkeit der Webseite zu verbessen. Durch Deinen Besuch stimmst Du dem zu.