webmatze.de

Profi Tipps für einen erfolgreichen Internetauftritt

FTP mit PHP

| 39 Kommentare

In diesem Artikel möchte ich mich etwas näher mit den Fähigkeiten von PHP auseinandersetzen. Ich möchte euch einen einfachen Weg zeigen, wie ihr mittels PHP eure Dateien auf einen FTP Server uploaden könnt. Warum man dies in PHP machen sollte und nicht etwa mit einem normalen FTP Client Programm? Nun, dafür gibt es mehrere Gründe.

Oft kann es vorkommen, das man sich hinter einer Firewall befindet und keinen Zugang auf den FTP Port erhält. Somit lassen sich keine FTP Clients verwenden. Oder man möchte Benutzern der eigenen Seite eine Möglichkeit bieten, Dateien per FTP auf den Server zu kopieren. Beides lässt sich mit einem simplen Formular und etwas PHP bewältigen. Doch kommen wir gleich zum Eingemachten.

Um FTP benutzen zu können, benötigen wir ein paar Funktionen, die ich im Folgenden näher erklären werde.

ftp_connect - Verbindung zum Host herstellen

Als allererstes müssen wir eine Verbindung zum FTP Host herstellen. Das geschieht mit der Funktion

ftp_connect(String Host, int[Port]).

  1. $ftp_server = "ftp.meinserver.de";
  2. $connection_id = ftp_connect($ftp_server);

Der Parameter Port ist optional und standardmäßig auf 21 eingestellt, was der Standard Port für FTP ist.

ftp_login - Anmelden einer FTP-Verbindung

Nachdem wir eine Verbindung zum Host hergestellt haben, müssen wir uns nur noch mit Benutzernamen und Passwort anmelden. Die dazugehörige Funktion in PHP lautet

ftp_login (int conn_id, string Benutzername, string Passwort).

  1.  
  2. $benutzername = "Benutzername";
  3. $passwort = "Passwort";
  4. $login_result = ftp_login($connection_id, $benutzername, $passwort);
  5.  

Wenn alles gutgegangen ist, haben wir jetzt Zugriff auf die Dateien. Nun müssen wir nur noch die gewünschte Datei hochladen.

ftp_put - Datei auf den FTP Server übertragen

Sehen wir uns zuerst einmal die Funktion an.

ftp_put (int conn_id, string Zieldatei, string Lokale_Datei, int Modus)

Lokale_Datei ist hierbei die Datei die als Datei namens Zieldatei auf dem Server gespeichert werden soll. Wichtig ist auch der Parameter Modus, der bestimmt ob die Datei im binären (FTP_BINARY) oder im ASCII (FTP_ASCII) Modus übertragen wird. In unserem Beispiel würde das Ganze dann wie folgt aussehen:

  1.  
  2. $zieldatei = "test.htm";
  3. $lokale_datei = "test.htm";
  4. $upload = ftp_put ($connection_id, $zieldatei, $lokale_datei, FTP_ASCII);
  5.  

ftp_quit - Die FTP Verbindung wieder schließen

Wenn alles erledigt wurde, was zu erledigen war, müssen wir die Verbindung auch wieder schließen. Ordnung muß sein. Die dazugehörige Funktion ist sehr simple.

ftp_quit(int conn_id)

Sie ist so simple, das ich jetzt kein Beispiel zeigen möchte, sondern lieber gleich alles in einem großen Script zusammenfasse.

Das fertige Script

Als Beispiel möchte ich euch ein einfaches Script zeigen, das es Besuchern erlaubt Textdateien auf einen gewünschten FTP Server zu laden. Dazu können sie die Datei mit folgendem Formular auswählen und abschicken:

  1. <title>Datei Upload</title>
  2. </head>
  3.  
  4. <body bgcolor="#FFFFFF" text="#000000">
  5. <h1>Schicken Sie uns ihre Texte</h1>
  6. <form action="ftpbeispiel.php" enctype="multipart/form-data" method="POST">
  7.  
  8. <p> Wählen Sie eine Textdatei (txt, html usw.)
  9. von Ihrem Rechner aus:<br />
  10. <input name="lokale_datei" type="file"
  11. size="50" maxlength="1024" accept="text/*">
  12.  
  13. </p>
  14. <p>Verzeichnis/Zieldatei<br>
  15. <input type="text" name="zieldatei">
  16. </p>
  17.  
  18. <input type="submit" name="Abschicken"
  19. value="Abschicken">
  20. </p>
  21.  
  22. </form>
  23. </body>
  24. </html>
  25.  

Ist das Formular ausgefüllt und abgeschickt, werden die Daten an das folgende Script gesendet und dort verarbeitet. Die drei ersten Variablen müssen noch an den eigenen FTP Server angepasst werden. Die Dateien werden relativ zu dem Verzeichnis abgelegt, in dem sich dieses Script befindet.

  1.  
  2. <?php
  3. // Diese Variablen bitte ändern
  4. $ftp_server = "ftp.meinserver.de";
  5. $benutzername = "mustermann";
  6. $passwort = "geheim";
  7.  
  8. // Die Verbindung herstellen
  9. $connection_id = ftp_connect($ftp_server);
  10.  
  11. // Mit Benutzername und Kennwort anmelden
  12. $login_result = ftp_login($connection_id, $benutzername, $passwort);
  13.  
  14. // überprüfen ob alles gutgegangen ist
  15. if ((!$connection_id) || (!$login_result)) {
  16. echo "<H1>Ftp-Verbindung nicht hergestellt!<H1>";
  17. echo "<P>Verbindung mit ftp_server als Benutzer $benutzername nicht möglich!</P>";
  18. die;
  19. } else {
  20. echo "<P>Verbunden mit ftp_server als Benutzer $benutzername</P>";
  21. }
  22.  
  23. // Die aus dem Forumular übergebenen Daten abfragen
  24. $zieldatei = $_POST['zieldatei'];
  25. $lokale_datei = $_POST['lokale_datei'];
  26.  
  27. // Hochladen der datei
  28. $upload = ftp_put($connection_id, $zieldatei, $lokale_datei, FTP_ASCII);
  29.  
  30. // Upload-Status überprüfen
  31. if (!$upload) {
  32. echo "<P>Ftp upload war fehlerhaft!</P>";
  33. } else {
  34. echo "<P>Datei $slokale_datei auf $host als $zieldatei geschrieben</P>";
  35. }
  36.  
  37. // Schließen der Verbindung
  38. ftp_quit($connection_id);
  39. ?>
  40.  

So jetzt alles auf euren Server laden und fertig.

Wichtig!

Da es dieses Script jedem erlaubt Dateien auf euren Server zu laden, solltet ihr es mit Bedacht einsetzen. Denkbar wäre ein Passwortschutz und eine Beschränkung der Dateigröße.

Diese Artikel könnten dich auch interessieren:

  • http://www.diekrabbe.de DieKrabbe

    Deine Beschreibung ist ja soweit tranzparent und sachlich. Doch ich vermisse hier die Übergabe der $_POST Variablen aus dem HTML Teil an den PHP Teil.

    Du schreibst:

    // Hochladen der datei
    $upload = ftp_put($connection_id, $zieldatei, $lokale_datei, FTP_ASCII);

    Doch wo in der PHP werden die Variablen $zieldatei oder $lokale_datei definiert?

  • http://webmatze.de webmatze

    In dem Formular kannst du zwei Felder sehen, welche diese Variablen beim Absenden dann an das Script übergeben.

    Je nach PHP Einstellungen muss man sich diese möglicherweise auch erst holen:


    $zieldatei = $_POST['zieldatei'];
    $lokale_datei = $_POST['lokale_datei'];

  • l4mp

    Er geht davon aus, dass register_globals aktiviert ist-

  • http://www.ulmerfeld-hausmening.at.tt PhilipKupsik

    Ich bekomme immer wieder die Fehlermeldung:

    Verbunden mit ftp_server als Benutzer ulmerfeld

    Ftp upload war fehlerhaft!

    und was müsste ich eigendlich in das zweite feld reinschreiben?

    • webmatze

      meinst du mit dem zweiten Feld $lokale_datei = $_POST['lokale_datei']?
      Das ist der Name der datei, wie er vom input type=“file“ Tag übergeben wird. Also die von der lokalen Festlplatte ausgewählte Datei.
      Über zieldatei wird festgelegt, wie die Datei nach dem Upload auf dem Server heißen soll.

  • Sandro

    Was läuft bei mir denn bitte Falsch?

    Fatal error: Call to undefined function: ftp_connect() in /mnt/web6/5

    • http://webmatze.de webmatze

      Das kann damit zu tun haben, dass bei deiner PHP Installation die FTP Funktionen nicht mit geladen/Installiert wurden.
      Diese werden normalerweise mit –enable-ftp bei der Installation mit installiert.
      Vielleicht solltest du dies mal auf deinem Server prüfen, oder deinen Hoster fragen, ob er die FTP Funktionen für PHP aktivieren kann.

  • Ben

    Einloggen klappt … diverse Tests haben auch schon geklappt … bei Wiederholungen
    öfter mal Fehlermeldungen :-( … aber eigentlich würde mich mehr interessieren, wie man das Script anpassen muss, wenn man einen Remote Upload starten möchte – sprich: nicht vom/über den eigenen Rechner hochladen, sondern direkt einen Link zu der Datei im Netz eingeben und Upload starten … hatte folgendes Script schon mal gefunden und erfolgreich getestet (schreibt aber die Dateien in das Verzeichnis wo es selbst liegt und leitet sie nicht an einen FTP-Server weiter) und es wäre meine Frage, ob man nicht beide Scripts irgendwie verknüpfen könnte um einen Remote Upload hinzubekommen???

    Remote Download Script

    body {background: black; color: white;}
    a:link {color: #CCFFFF}
    a:visited {color: #FFFFFF}
    a:hover {color: #99FFFF}
    a:active {color: #66FFFF}

    Remote Download Script

    Remote File:
    Local File:    

    31556926,’month’=>2629743,’day’=>86400,’hour’=>3600,’minute’=>60,’second’=>1);
    $flag_hide_zero = true;
    foreach( $periods as $key => $length )
    {
    $temp = floor( $int_seconds / $length );
    if( !$flag_hide_zero || $temp > 0 )
    {
    $build[] = $temp.‘ ‚.$key.($temp!=1?’s':null);
    $flag_hide_zero = false;
    }
    $int_seconds = fmod($int_seconds, $length);
    }
    return ( !empty($build)?implode(‚, ‚, $build):$if_reached );
    }
    if(!is_writeable(‚./‘)) {
    exit(‚Cannot write to local dir (needs chmod).‘);
    }
    $remote_file = $_POST[‚url‘];
    if($_POST[‚output‘]) {
    $local_file = $_POST[‚output‘];
    } else {
    $decoded_url = rawurldecode($remote_file);
    $local_file = substr($decoded_url, strrpos($decoded_url, ‚/‘) + 1);
    }
    if(file_exists($local_file)) {
    unlink($local_file);
    echo(„$local_file has Been Replaced“);
    }
    if($remote_file) {
    $startTime = time();
    set_time_limit(0);
    ignore_user_abort();
    $file_in = fopen($remote_file, ‚r‘);
    $file_out = fopen(‚./‘.$local_file, ‚a‘);
    if($file_in) {
    while(!feof($file_in)) {
    $buffer = fread($file_in, 8192);
    fwrite($file_out, $buffer, 8192);
    }
    fclose($file_in);
    fclose($file_out);
    $size = filesize($local_file);
    $humansize = human_file_size($size);
    $seconds = time() – $startTime;
    if($size <= 10240) {
    unlink($local_file);
    exit(„$local_file has been deleted“);
    }
    $count = duration($seconds);
    $url = rawurlencode($local_file);
    exit(„Filename: $local_fileFilesize: $humansizeTime: $count“);
    }
    }
    exit;
    ?>

  • matthias

    hi
    hab mir das ganze mal testweise geschnappt und ausprobiert aber ich finde die hochgeladenen datein nicht…. ´wohin werden die gespeichert?

  • matthias

    aha ins root verzeichnis aber warum sind meine datein alle 0kb groß

  • Stefan

    hi ich habe jetzt das probiert aber es funktioniert einfach nicht bei mir. wie genau sehen die angaben für diese felder aus?:

    $zieldatei = „test.htm“;
    $lokale_datei = „test.htm“;

    Angenommen, der Dateistring auf dem PC ist „C:\Windows\test.txt“

    die indexphp liegt auf dem server im verzeichnis „/htdocs/index.php“
    und jetzt soll auch in diesen ordner die „test.txt“ hingeladen werden also: „/htdocs/test.txt“

    Bin dankbar für jede hilfe.
    MfG Stefan

  • http://webmatze.de webmatze

    Ich habe das Script mal mit den Anregungen aus den Kommentare erweitert. Die Parameter $zieldatei und $lokale_datei werden natürlich über das abgesendete HTML Forumular gefüllt und vom PHP Script ausgelesen.
    $lokale_datei ist dabei die über das Dateiauswahlfeld ausgewählte Datei, die Hochgeladen werden soll. $zieldatei ist der Name der Datei, so wie sie auf dem Server heißen soll. Im Idealfall könnte man den Namen der $zieldatei auch aus dem Namen der Variable $lokale_datei parsen. Aber das würde den Ramen dies Artikels sprengen.
    PHP läd die Dateien standardmäßig in ein definiertes Upload Verzeichnis. Dies kann in der php.ini angegeben werden. Der nächste Schritt wäre also, dass man die Datei aus dem Temporären Verzeichnis in das eigentliche Zielverzeichnis kopiert. Auch dies wird in unserem einfachen Script nicht gemacht.
    Das hier beschriebene Script soll eigentlich nur die FTP Funktionen von PHP an einem einfachen Script zeigen.

  • Pingback: Websiteinhalte von zuhaus - netzwelt.de Forum()

  • Pingback: Upgeloadete Datei lokal speichern - php.de()

  • http://www.foxpoint.de Werner

    Vieleicht sollte man es lieber mit $_FILE[„lokale_datei“][„tmp_name“]
    machen ???

    Gruss.

  • htmlfreak

    @Werner: [quote]$_FILE[„lokale_datei“][„tmp_name“]
    machen ??? [/quote]

    Ja allerdings :D aber sonst gut beschrieben

  • http://www.funk.it alex

    Hi,
    hab mir das auch angeschaut und es fehlt was grundlegendes…
    Ihr ladet zuerst eine Datei auf einen Server, dann muss die Datei auf dem Server geöffnet werden und per FTP übertragen werden.

    $uploaddir = “;
    $uploadfile = $uploaddir. basename($_FILES[‚lokale_datei‘][‚name‘]);

    if (move_uploaded_file($_FILES[‚lokale_datei‘][‚tmp_name‘], $uploadfile)) {

    } else {
    print „Possible file upload attack! Here’s some debugging info:\n“;
    print_r($_FILES);
    }

    $ftp_server = „ftp.yourserver.de“;
    $benutzername = „ben“;
    $passwort = „pw“;

    // Die Verbindung herstellen
    $connection_id = ftp_connect($ftp_server);

    // Mit Benutzername und Kennwort anmelden
    $login_result = ftp_login($connection_id, $benutzername, $passwort);
    ftp_pasv($connection_id, true);

    // überprüfen ob alles gutgegangen ist
    if ((!$connection_id) || (!$login_result)) {
    echo „Ftp-Verbindung nicht hergestellt!“;
    echo „Verbindung mit ftp_server als Benutzer $benutzername nicht möglich!“;
    die;
    } else {
    echo „Verbunden mit ftp_server als Benutzer $benutzername“;
    }

    // Die aus dem Forumular übergebenen Daten abfragen
    $zieldatei = $uploadfile;
    $lokale_datei = $uploadfile;
    $fp = fopen($lokale_datei, ‚r‘);

    // Hochladen der datei
    echo $connection_id.“ „.$zieldatei.“ „.$lokale_datei;
    $upload = ftp_put($connection_id, $zieldatei, $lokale_datei, FTP_ASCII);

    // Upload-Status überprüfen
    if (!$upload) {
    echo „Ftp upload war fehlerhaft!“;
    } else {
    echo „Datei $lokale_datei auf $ftp_server in $zieldatei geschrieben“;
    }

    // Schließen der Verbindung
    ftp_quit($connection_id);

  • Anhktus

    Warning: ftp_put() [function.ftp-put]: Filename cannot be empty

    was soll mir das nun sagen? datei is aufm rechner vorhanden und ausgewählt, und ich bekomm diese nette meldung…

  • StremmeNizer

    @ alex und @ ben.

    Gebt doch mal ne Quelle an, wenn ihr Copy Pastet.

    @ Anhktus

    Kann sein, dass du den Zielnamen nicht deklarirst, sondern nur den Lokalen ausliest.
    wenn du zum beispiel „test.htm“ auswählst und uploadest, will er die vllt als „.htm“ speichern:

    $zieldatei = $lokale_datei

    ganz einfach, dann heißt die datei aufm server genau wie bei dir lokal

  • http://www.willnat.org Florian

    Woran könnte es liegen, das meine hochgeladenen Dateien alle 0kb groß sind ???

  • http://webmatze.de webmatze

    Vielleicht hilft dir dies weiter:

    http://www.php.net/manual/en/function.ftp-fput.php#90517

    Möglicherweise ein Problem mit einer Firewall oder Dateirechten auf dem Server.

  • JU

    Hi.

    Der Fehler im Script is das von der lokalen datei nur der name über nommen wird und nicht der pfad wo die datei liegt!
    Auserdem sollte man bei zielname auch noch den pfadt mit ./Name_der_Ziel_Datei.txt kennzeichnen

    Aber sonst top die erklärung
    LG
    JU

  • Bob

    Hallo zusammen,
    könnte mir bitte jemand eine lokale Pfadangabe als Beispiel posten? Bei mir sollte von C:\test.txt upgeloadet werden, funzt aber nicht, weil wahrscheinlich die Pfadangabe nicht korrekt ist.
    Danke schon mal

  • http://webmatze.de webmatze

    Also du gibst ja eigentlich nicht den Pfad der lokalen Datei an, sondern wählst diese über das Formular mit dem INPUT type=“file“ aus.

  • Bob

    Ja, aber das muß doch auch über eine direkte Pfadangabe gehen, wenn z.B. die Datei immer dieselbe (bzw. modifizierte) ist.
    Auf Knopfdruck soll die Datei hochgeschoben werden.

  • Philipp

    gibt es für den Befehl

    $connection_id = ftp_connect($ftp_server);

    noch einen anderen Befehl für eine ältere ftp version?

    • http://webmatze.de webmatze

      Soweit ich weiß eigentlich nicht. Wieso fragst du? Bekommst du einen Fehler?

  • Philipp

    ja, diesen

    /var/tmp/php/phprgjgnC
    Fatal error: Call to undefined function: ftp_connect()

    hab aber rausgefunden das der server den befhel unterstützen müsste, wodran kann es sonst liegen?

  • Pingback: About | Code-Schnipsel()

  • froesch

    erstmal möchte ich zip und rar dateien verwenden nicht nur txt files. was muß ich dazu ändern?

    ach und bei mir lädt rein gar nix hoch

    http://froesch.square7.ch/

  • froesch

    kann man nicht auch irgendwie sagen, dass lokale datei = zieldatei ist? das würde die sache um einiges vereinfachen

  • Flasher2002

    Hallo zusammen,

    hab mich heute auch mit diesem „Problem“ rumgeschlagen. Viele Anregungen ausprobiert, dabei war die Lösung wirklich schmal und mit ein paar Zeilen Code umsetzbar. Der Cloue: Man(n) braucht die FTP-Funktion für den Upload der Datei überhaupt nicht. Mein Skript sieht nach dem ganzen Tamtam wie folgt aus:

    Für die Kritiker… ja, ich weis, es sind keine Fehlerroutinen drin usw… usw… aber das darf sich dann jeder selbst nach Bedarf zusammenstricken. Wichtig ist für mich: ES FUNKTIONIERT!

    Hintergrund:
    Nach Auswahl der lokalen Datei und absenden des Formulars wird eine temporäre Kopie der Datei auf dem Server abgelegt. Diese muss mann dann mittels „copy“ in das gewünschte Zielverzeichnis kopieren oder mit „move_uploaded_file“ verschieben. Das Zielverzeichnis habe ich vorsorglich mit dem CHMOD 777 belegt.

  • Peter Brocal

    Also ich verwende PHFTP. Ein Opensource FTP Client in PHP geschrieben. Das erspart viel Quirks. Läuft auf jedem Apache denke ich und war kinderleicht zu konfigurieren.

  • Peter Brocal

    Nachtrag: Man findet PHFTP mit Google, oder auf https://sourceforge.net/projects/phftp/

    Grüsse,

    peter

  • Maurice

    Hallo,
    da funktioniert etwas nicht

    Warning: ftp_put() [function.ftp-put]: Filename cannot be empty in C:\xampp\htdocs\2.php on line 27

  • http://gravatar.com/elmatrixco Kerim

    Ersetzt die Zeile 25 durch folgenden code:

    $lokale_datei = $_FILES[‚lokale_datei‘][‚tmp_name‘];

    Dann klappts :-)

  • Roland Hentschel

    Der Upload an sich funktioniert. Aber wie kann man den Fortschritt verfolgen?
    Hab‘ mir irgendwas in dieser Art vorgestellt :

    header( „refresh:10; url=progress.php?tmp_file=“.$_REQUEST[„tmp_file“] );
    include („login.inc“);
    // $ftp_server = ???
    // $ftp_user_name = ???
    // $ftp_user_pass = ???
    $file = $_REQUEST[„tmp_file“]; // $_FILES[„userfile“][„tmp_name“];
    // set up basic connection
    $conn_id = ftp_connect($ftp_server);
    // login with username and password
    $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
    // get the size of $file
    $res = ftp_size($conn_id, $file);
    if ($res != -1) { echo „size of $file is $res bytes“;
    } else { echo „couldn’t get the size“; }
    // close the connection
    ftp_close($conn_id);

    Aber leider, leider – ich krieg’s nicht hin …

    • http://webmatze.de webmatze

      Dazu solltest du dir mal diese Funktion von PHP anschauen:
      http://www.php.net/manual/en/session.upload-progress.php

      Vielleicht hilft dir das weiter. Ich selbst habe solche eine Funktion bisher noch nicht umgesetzt.
      Zumal einige Browser heute auch schon den aktuellen Uploadstatus in Prozent anzeigen.

  • ChrisPHPnewbie

    Ist zwar schon älter das Script, habe aber leider nichts vergleichbares gefunden.

    Mich
    würde interessieren, wie man auf einem Rechner mittels PHP eine
    Txt.Datei erstellt, die das Inhaltsverzeichnis beinhaltet (mit DOS
    wüsste ich es) und wie man eine (oder mehrere) bekannte txt.Dateien
    hochlädt (also ohne vorher in einem Formular einzutragen)

    Gruß,Chris