[PHP] upload via FTP

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Hey mensjes. ^^

Ik probeer met PHP een bestand te uploaden via FTP, hier heb ik een functie voor gevonden op zend.com, dit functioneert als ik een hard bestand upload, dus duidelijk bij het aanroepen van de class/functie aangeef dat het bestand 'daar' staat.

Nu wil ik dit dynamisch hebben, dus dat je via een formulier upload (multipart/form-data), maar telkens krijg ik de meldign dat het bestand niet gevonden kan worden. Als ik vervolgens het bestand plaats in de map waar ik de class en het php bestand heb staan werkt het wel, maar dat is natuurlijk niet echt de bedoeling. ^^

Heb ook al verschillende methoden geprobeert via $_FILES, maar dit leverde ook geen goed resultaat op. Als ik $_FILES['bestand']['name'] vraag, dan krijg ik alleen het bestandsnaam, en via de andere geprobeerdemethoden ook. Weet iemand wat ik fout doe, of is het gewoon niet mogelijk dit te doen? (Wat me overigens erg sterk lijkt)

class.phpftp.php
class php_ftp {

public $server = '';
public $usernam = '';
public $password = '';
public $port = 21;
public $remote_dir = '';

function php_ftp($server, $username='anonymous', $password='e@mail.com', $port=21) {
$this->server = $server;
$this->usernam = $username;
$this->password = $password;
$this->port = $port;
}

function send($filename='', $save_as='', $passive=TRUE) {
$conn = $this->return_connection() or die;
@ftp_pasv($conn, $passive);
$this->set_remote_dir(ftp_pwd($conn));
if(!ftp_put($conn, $save_as, $filename, FTP_BINARY)) {
@ftp_put($this->conn);
return false;
} else {
@ftp_put($this->conn);
return true;
}
return true;
}

function get($filename='', $save_as='', $passive=TRUE) {
$conn = $this->return_connection() or die;
@ftp_pasv($conn, $passive);
$this->set_remote_dir(ftp_pwd($conn));
if(!ftp_get($conn, $save_as, $this->remote_dir.$filename, FTP_BINARY)) {
@ftp_quit($this->conn);
return false;
} else {
@ftp_quit($this->conn);
return true;
}
}

function kill() {
if($this->conn) {
$this->disconnect();
}
unset($this);
}

function return_connection() {
$conn_id = @ftp_connect($this->server, $this->port) or die ("Kan geen verbinding maken met de FTP server.");
$login_result = @ftp_login($conn_id, $this->usernam, $this->password) or die ("Kan niet inloggen.");
return $conn_id;
}

function set_remote_dir($dir) {
$x = substr($dir, (strlen($dir)-1));
if($x != "/" && $x != "\\") {
$dir .= "/";
}
$this->remote_dir = $dir;
}

}
index.php
require_once('class.phpftp.php');

if($_POST) {
$bestand = basename($_FILES['bestand']['name']);
$doel = $_POST['doel'];
$naam = $_POST['naam'];
$ftp = new php_ftp('127.0.0.1', 'psyed', 'kelvin');
$ftp->send($bestand, $naam) or die ("Bla");
$ftp->kill();
} else {
$echo = <<<EOHTML
<form method="post" action="index.php" enctype="multipart/form-data">
Bestand <input type="file" name="bestand"><br>
Doel <input type="text" name="doel"><br>
Naam <input type="text" name="naam"><br>
<input type="submit" value="Test!">
</form>
EOHTML;

print $echo;
}

Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat je eerst move_uploaded_file moet gaan gebruiken, naar een "lokale map" op de server. Vervolgens je class aanroepen om de daadwerkelijke ftp-upload te doen.

Acties:
  • 0 Henk 'm!

Verwijderd

btw... ik zie dat je de file ftp'd naar 127.0.0.1, wat is je bedoeling met dit script eigenlijk??

Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Verwijderd schreef op maandag 16 oktober 2006 @ 13:58:
btw... ik zie dat je de file ftp'd naar 127.0.0.1, wat is je bedoeling met dit script eigenlijk??
Ik test het script momenteel nog op mijn laptop, m'n ontwikkelomgeving. De uiteindelijke bedoeling is dat medewerkers het systeem kunnen gebruiken om bestanden er in te kunnen zetten, die dan vervolgens door de klant weer gedownload kunnen worden.

Er van uit gaande dat het gros niet eens weet hoe dat ze via een normale tool moeten uploaden. Op deze manier hoeven wij als programmeurs minder werk er aan te verrichten.

Acties:
  • 0 Henk 'm!

  • Leedbek
  • Registratie: November 2004
  • Laatst online: 12:44

Leedbek

Luuk Luchtloper

Waarom zo moeilijk doen met ingewikkelde classes als je met de standaard ftp-functies van php hetzelfde kunt bereiken? Kijk anders eens naar de beschrijving van ftp_put in de php manual, zoiets kan met 5 regels code gefixt worden.

Klaar voor de steroorlogen?


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Verwijderd schreef op maandag 16 oktober 2006 @ 13:57:
Ik denk dat je eerst move_uploaded_file moet gaan gebruiken, naar een "lokale map" op de server. Vervolgens je class aanroepen om de daadwerkelijke ftp-upload te doen.
Met move_uploaded_file? Dan kan ik net zo goed de 'standaard' uploadmethode gebruiken lijkt me. ;) Het beste lijkt ons om dit via FTP op te lossen, aangezien we het over bestanden van enkele tientallen mb's hebben (enkele bestanden van over de 100 mb).

We willen het liefst ook niet tijdelijk de php_ini aanpassen, maar als het niet anders gaat, dan moet het wel zo. ^^

Edit:
max_file_size (in php.ini) kan, volgens een collega, niet aangepast worden.

[ Voor 6% gewijzigd door Psyed op 16-10-2006 14:16 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Je weet neem ik aan dat het script op de server draait, en niet op de client. Wil je een bestand van de client gaan FTP-en dan is dit onmogelijk om met php te doen. Feitelijk komt het er dan op neer dat je eerst het bestand via http upload om hem vervolgens van de server naar de server te ftp-en. Een php script heeft (gelukkig!!) geen toegang tot de harde schijf van de bezoeker.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Luuk-Online schreef op maandag 16 oktober 2006 @ 14:05:
Waarom zo moeilijk doen met ingewikkelde classes als je met de standaard ftp-functies van php hetzelfde kunt bereiken? Kijk anders eens naar de beschrijving van ftp_put in de php manual, zoiets kan met 5 regels code gefixt worden.
Dit is nog baar de beginfase, uiteindelijk moet het beheer hier van volledig web-based (zonder ftp-tools) lopen.

En ftp_put retourneert de zelfde fout als het gaan om 'variabele' bestanden (formulier).

Acties:
  • 0 Henk 'm!

  • Foxl
  • Registratie: Juli 2002
  • Niet online
We willen het liefst ook niet tijdelijk de php_ini aanpassen, maar als het niet anders gaat, dan moet het wel zo. ^^

Edit:
max_file_size (in php.ini) kan, volgens een collega, niet aangepast worden.
Je hebt wel door dat je op de manier die je nu gebruikt de bestanden ook eerst naar de server post? Als je bestanden meteen vanaf de PC van de gebruiker wilt gaan FTPen, dat gaat je (godzeidank) niet lukken.

I'm really easy to get along with, once you people learn to worship me...


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Janoz schreef op maandag 16 oktober 2006 @ 14:08:
Je weet neem ik aan dat het script op de server draait, en niet op de client. Wil je een bestand van de client gaan FTP-en dan is dit onmogelijk om met php te doen. Feitelijk komt het er dan op neer dat je eerst het bestand via http upload om hem vervolgens van de server naar de server te ftp-en. Een php script heeft (gelukkig!!) geen toegang tot de harde schijf van de bezoeker.
Dat snap ik hopelijk ja. ;)

Goed, het komt er dus op neer dat het gewoon niet mogelijk is om dit via php op te lossen is, gezien de meeste filesizes. Maar hoe zit het dan met move_uploaded_files, daar zit toch een limiet aan (in de php.ini), die niet via php-scripts aan te passen is? Of is daar ergens een work-around voor?

Acties:
  • 0 Henk 'm!

  • Leedbek
  • Registratie: November 2004
  • Laatst online: 12:44

Leedbek

Luuk Luchtloper

Psyed schreef op maandag 16 oktober 2006 @ 14:10:
[...]


Dit is nog baar de beginfase, uiteindelijk moet het beheer hier van volledig web-based (zonder ftp-tools) lopen.

En ftp_put retourneert de zelfde fout als het gaan om 'variabele' bestanden (formulier).
Ik heb voor een cms een soortgelijk script geschreven, dat werkt met een multipart/form-data upload-formulier, wat vervolgens met ftp_put op z'n plek wordt gezet op de server. Werkt perfect, en is volledig web-based.
Kun je anders de foutmelding hier plaatsen? Ik vermoed dat er een fout zit in het pad waar je het bestand naar wilt uploaden.

Klaar voor de steroorlogen?


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Luuk-Online schreef op maandag 16 oktober 2006 @ 14:22:
[...]

Ik heb voor een cms een soortgelijk script geschreven, dat werkt met een multipart/form-data upload-formulier, wat vervolgens met ftp_put op z'n plek wordt gezet op de server. Werkt perfect, en is volledig web-based.
Kun je anders de foutmelding hier plaatsen? Ik vermoed dat er een fout zit in het pad waar je het bestand naar wilt uploaden.
Warning: ftp_put(test_file.txt) [function.ftp-put]: failed to open stream: No such file or directory in F:\xampp\xampp\htdocs\test\class.phpftp.php on line 31

test_file.txt is het bestand dat ik probeer te uploaden.

Acties:
  • 0 Henk 'm!

  • Leedbek
  • Registratie: November 2004
  • Laatst online: 12:44

Leedbek

Luuk Luchtloper

Psyed schreef op maandag 16 oktober 2006 @ 14:27:
[...]


Warning: ftp_put(test_file.txt) [function.ftp-put]: failed to open stream: No such file or directory in F:\xampp\xampp\htdocs\test\class.phpftp.php on line 31

test_file.txt is het bestand dat ik probeer te uploaden.
Je moet het bestand test_file.txt wel vooraf laten gaan aan het juiste ftp-pad, en het is een string dus moet het tussen " tekens komen te staan. Dan wordt het bijvoorbeeld:
PHP:
1
ftp_put("/httpdocs/dirnaam/test_file.txt");


Het gedeelte "/httpdocs/" is natuurlijk afhankelijk van je eigen server.

Klaar voor de steroorlogen?


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Luuk-Online schreef op maandag 16 oktober 2006 @ 14:31:
[...]

Je moet het bestand test_file.txt wel vooraf laten gaan aan het juiste ftp-pad, en het is een string dus moet het tussen " tekens komen te staan. Dan wordt het bijvoorbeeld:
PHP:
1
ftp_put("/httpdocs/dirnaam/test_file.txt");


Het gedeelte "/httpdocs/" is natuurlijk afhankelijk van je eigen server.
Thanks voor de hulp. Het probleem zat hem er in dat we geen toegang hebben om een bestand van een andere pc te halen via ftp. (Jammer, maar zeker begrijpelijk).

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Ik heb ooit eens een script gemaakt gehad, die een bestand die via HTTP geupload werd, naar een andere FTP geupload werd... Je moet gewoon een filepointer maken naar iets uit $_FILES.
Welke dat dit is weet ik (helaas) niet meer, kan best zijn dat je dat moet doen middels move_uploaded_file($_FILES['name']).

Hou er overigens rekening mee dat $this->usernam altijd leeg zal zijn... ;) Je global var heet namelijk $usernam ipv $username... ;)
PHP:
1
$ftp->send($bestand, $naam) or die ("Bla");
Is niet echt slimme foutafhandeling IMO...
Lijkt mij dat $ftp->send een false returned als het senden niet lukt? :? Dus dan doe je toch zoiets als
PHP:
1
2
$send = $ftp->send($bestand, $naam);
if(!$send){ echo 'Uploaden mislukt.'; }
Pas dus op zijn minst bij je or die("Bla") die Bla aan... ;)

[ Voor 28% gewijzigd door CH4OS op 16-10-2006 15:15 ]


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
GJ-tje schreef op maandag 16 oktober 2006 @ 14:57:
Ik heb ooit eens een script gemaakt gehad, die een bestand die via HTTP geupload werd, naar een andere FTP geupload werd... Je moet gewoon een filepointer maken naar iets uit $_FILES.
Welke dat dit is weet ik (helaas) niet meer, kan best zijn dat je dat moet doen middels move_uploaded_file($_FILES['name']).

Hou er overigens rekening mee dat $this->usernam altijd leeg zal zijn... ;) Je global var heet namelijk $usernam ipv $username... ;)
Lol, die typo niet eens gezien. :p Thanks. ^^

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Psyed schreef op maandag 16 oktober 2006 @ 14:21:
[...]


Dat snap ik hopelijk ja. ;)

Goed, het komt er dus op neer dat het gewoon niet mogelijk is om dit via php op te lossen is, gezien de meeste filesizes. Maar hoe zit het dan met move_uploaded_files, daar zit toch een limiet aan (in de php.ini), die niet via php-scripts aan te passen is? Of is daar ergens een work-around voor?
Volgens mij heb je het nog steeds niet begrepen. move_uploaded_files verplaatst gewoon het bestand op de server. Wanneer je een formulier hebt met hierin een bestand en dit formulier submit gebeurt het volgende:
- IE stuurt een request naar de server en hierin wordt het bestand gezet
- Het bestand wordt nu dus in zijn geheel geupload
- Apache schrijft het binnengekomen bestand weg naar de temp directory
- Apache merkt dat het hele request binnen is en start php op om het request te verwerken
- je php code wordt utigevoerd en als je hier een move_uploaded_file in hebt staan wordt het vanuit de temp directory verplaatst naar de plek die je wilt hebben
- de gegenereerde pagina wordt naar de client gestuurd.

Door FTP te gaan gebruiken stap je pas in op het op 1 na laaste punt. Het hele bestand is dus al lang en breed geupload door de gebruiker.

De ftp class heeft alleen nut wanneer je het bestand vervolgens naar een andere server wilt sturen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Janoz schreef op maandag 16 oktober 2006 @ 15:38:
[...]

Volgens mij heb je het nog steeds niet begrepen. move_uploaded_files verplaatst gewoon het bestand op de server. Wanneer je een formulier hebt met hierin een bestand en dit formulier submit gebeurt het volgende:
- IE stuurt een request naar de server en hierin wordt het bestand gezet
- Het bestand wordt nu dus in zijn geheel geupload
- Apache schrijft het binnengekomen bestand weg naar de temp directory
- Apache merkt dat het hele request binnen is en start php op om het request te verwerken
- je php code wordt utigevoerd en als je hier een move_uploaded_file in hebt staan wordt het vanuit de temp directory verplaatst naar de plek die je wilt hebben
- de gegenereerde pagina wordt naar de client gestuurd.

Door FTP te gaan gebruiken stap je pas in op het op 1 na laaste punt. Het hele bestand is dus al lang en breed geupload door de gebruiker.

De ftp class heeft alleen nut wanneer je het bestand vervolgens naar een andere server wilt sturen.
Dat had ik al begrepen. ;) Het is natuurlijk erg onlogisch om iets te uploaden naar een server en het dan vervolgens nog eens te verplaatsen, genereert data die totaal niet nodig is.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Dat verplaatsen (met move_uploaded_file) is geen probleem en genereert ook geen traffic. Dit kopieerd gewoon het bestand vanuit de temp directory naar de plaats waar je het wilt hebben. Tenzij je met verplaatsen FTP-en naar localhost bedoeld, dat is inderdaad onnodig*.


*In sommige exotische gevallen wordt het nog wel eens gebruikt bij een te restrictieve rechteninstelling op de server. Gewoon kopieren zou betekenen dat het bestand van de apacheuser wordt en niet van de eigenaar van de website.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Psyed
  • Registratie: Oktober 2003
  • Laatst online: 19-07 11:58
Janoz schreef op maandag 16 oktober 2006 @ 16:29:
Dat verplaatsen (met move_uploaded_file) is geen probleem en genereert ook geen traffic. Dit kopieerd gewoon het bestand vanuit de temp directory naar de plaats waar je het wilt hebben. Tenzij je met verplaatsen FTP-en naar localhost bedoeld, dat is inderdaad onnodig*.


*In sommige exotische gevallen wordt het nog wel eens gebruikt bij een te restrictieve rechteninstelling op de server. Gewoon kopieren zou betekenen dat het bestand van de apacheuser wordt en niet van de eigenaar van de website.
Als we FTP zouden gaan gebruiken zou het idd van localhost naar localhost worden, zeer onlogisch. ;)

Ben zelf nog maar een stagair, hoor nog niet alles te weten. ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Is het probleem nou verholpen?? Ik volgde dit draadje vandaag maar weet niet of de TS z'n problemen heeft opgelost....

Wat ik je nog wel als tip wil meegeven, als je een normaal form gebruikt krijgt de User totaal geen feedback totdat het PHP script klaar is met reply-en... dwz bij een bestand van 100mb over een niet al te groot lijntje (wat me overigens bij "lokaal netwerk" gebruik niet reeel lijkt) ziet de gebruiker dus bijvoorbeeld 3 minuten een "ladende" browser. Dit wekt bij veel gebruikers het vermoeden dat er niets gebeurt.

Wat je hiertegen kan doen is AJAX gebruiken, er zijn op het web wel wat tut's te vinden die je uitleggen hoe je ondanks het gebruik van PHP toch een "laad" balkje kan zien, die aangeeft hoelang de upload vermoedelijk nog gaat duren!

bijvoorbeeld even snel gegoogled: http://www.devpro.it/upload_progress/

(weet niet of die werkt, maar never hurts to try.. tenminste..)

Succes!
Pagina: 1