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]).
$ftp_server = "ftp.meinserver.de";
$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).
$benutzername = "Benutzername";
$passwort = "Passwort";
$login_result = ftp_login($connection_id, $benutzername, $passwort);
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:
$zieldatei = "test.htm";
$lokale_datei = "test.htm";
$upload = ftp_put ($connection_id, $zieldatei, $lokale_datei, FTP_ASCII);
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:
Datei Upload
Schicken Sie uns ihre Texte
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.
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 = $_POST['zieldatei'];
$lokale_datei = $_POST['lokale_datei'];
// Hochladen der 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 $slokale_datei auf $host als $zieldatei geschrieben
";
}
// Schließen der Verbindung
ftp_quit($connection_id);
?>
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.
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?
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'];
Er geht davon aus, dass register_globals aktiviert ist-
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?
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.
Was läuft bei mir denn bitte Falsch?
Fatal error: Call to undefined function: ftp_connect() in /mnt/web6/5
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.
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;
?>
hi
hab mir das ganze mal testweise geschnappt und ausprobiert aber ich finde die hochgeladenen datein nicht…. ´wohin werden die gespeichert?
aha ins root verzeichnis aber warum sind meine datein alle 0kb groß
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
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.
Vieleicht sollte man es lieber mit $_FILE[„lokale_datei“][„tmp_name“]
machen ???
Gruss.
@Werner: [quote]$_FILE[„lokale_datei“][„tmp_name“]
machen ??? [/quote]
Ja allerdings :D aber sonst gut beschrieben
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);
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…
@ 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
Woran könnte es liegen, das meine hochgeladenen Dateien alle 0kb groß sind ???
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.
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
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
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.
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.
gibt es für den Befehl
$connection_id = ftp_connect($ftp_server);
noch einen anderen Befehl für eine ältere ftp version?
Soweit ich weiß eigentlich nicht. Wieso fragst du? Bekommst du einen Fehler?
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?
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/
kann man nicht auch irgendwie sagen, dass lokale datei = zieldatei ist? das würde die sache um einiges vereinfachen
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.
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.
Nachtrag: Man findet PHFTP mit Google, oder auf https://sourceforge.net/projects/phftp/
Grüsse,
peter
Hallo,
da funktioniert etwas nicht
Warning: ftp_put() [function.ftp-put]: Filename cannot be empty in C:\xampp\htdocs\2.php on line 27
Ersetzt die Zeile 25 durch folgenden code:
$lokale_datei = $_FILES[‚lokale_datei‘][‚tmp_name‘];
Dann klappts :-)
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 …
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.
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