Avatar billede kgp43 Nybegynder
29. juni 2005 - 20:59 Der er 35 kommentarer og
1 løsning

for mange uploads (phpftp)

Hejsa,

Jeg har et system for en bruger kan uploade filer.
Får ca 2.000 uploads per day (avg 4.3MB/upload), men ftp crasher konstant. Har fået at vide fra forskellige steder at det er ftp funktionen i php, der ikke kan håndterer denne form for load.

Systemet virker ved at brugeren uploader en fil via en standard upload form, bliver lagt i tmp folderen og efterfølgende FTP'ed til den korrekte filserver.

Alle filer bliver uploaded til tmp folderen uden problemer (kan echo filstørrelsen), men har problemer med at FTP til korrekt filserver. Dette problem opstår ved 50-60% af alle uploads over 1MB, men ikke ved alle.

Har prøvet det meste over de seneste 5-6 uger og fået hjælp fra diverse forums og developers, men har ikke fundet er løsning på mit problem. Løsningen skulle gerne kunne uploade 10.000 filer per day.

6 uger er lang til og jeg håber virkelig at en løsning kan findes inden for den næsmeste fremtid.

Nogle forslag til en løsning?
Har undersøgt muligheden for en anden ftp, men kan ikke finde en der kan erstatte ftp'en i php.
Avatar billede coderdk Praktikant
30. juni 2005 - 08:31 #1
Et godt alternativ er cURL: http://dk2.php.net/curl
Det kræver at der er kompileret support for det i PHP.
Avatar billede kgp43 Nybegynder
30. juni 2005 - 10:36 #2
hvad er fordelen ved curl?
Avatar billede coderdk Praktikant
30. juni 2005 - 11:12 #3
Den kan alt :)
Avatar billede kgp43 Nybegynder
30. juni 2005 - 11:15 #4
hehe, måske er det bare mig men deres manual for curl virker uoverskuelig og forvirrende. Skal den ikke "bare" bruges til at "download" en side eller fil ved brug af url'en?

kan du poste et eksempel hvordan kan flytter en fil fra én server til en anden?
Avatar billede coderdk Praktikant
30. juni 2005 - 14:20 #5
Det er lidt mere besværligt:

<?php

    $filnavn = 'filnavn.txt';
    $fp = fopen( $filnavn, 'r' );
    $stat = fstat( $fp );

    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, 'ftp://ftp.example.dk/folder/' . $filnavn );
    curl_setopt( $ch, CURLOPT_USERPWD, 'brugernavn:password' );
    curl_setopt( $ch, CURLOPT_INFILE, $fp );
    curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
    curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
    curl_exec( $ch );
    curl_close( $ch );

    fclose( $fp );

?>
Avatar billede kgp43 Nybegynder
30. juni 2005 - 15:11 #6
Bruger du standard phpftp når du skal oprette mapper og slette filer så?
Er der muligt at connecte til server IP istedet for url? Er dette korrekt (ved ikke lige hvordan jeg får server IP med ind)?

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'uploads/' . $filnavn );
curl_setopt( $ch, CURLOPT_USERPWD, 'brugernavn:password' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
curl_exec( $ch );
curl_close( $ch );
Avatar billede coderdk Praktikant
30. juni 2005 - 22:50 #7
Ja, du skal bare skrive IP i stedet for hostnavn, og du kan sende commands med den i samme hug tror jeg:

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://1.2.3.4/uploads/' . $filnavn );
curl_setopt( $ch, CURLOPT_USERPWD, 'brugernavn:password' );
curl_setopt( $ch, CURLOPT_POSTQUOTE, array( 'mkdir blah', 'cd blah' ) );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );

CURLOPT_POSTQUOTE tager et array og eksekverer kommandoerne på serveren, så vidt jeg kan læse mig til på php.net - Husk i øvrigt at kalde fclose( $fp ); :)
Avatar billede kgp43 Nybegynder
01. juli 2005 - 02:37 #8
curl_setopt( $ch, CURLOPT_URL, 'ftp://1.2.3.4/uploads/' . $filnavn );

- Vil det også virke når folderen er placeret udenfor public_html?
Avatar billede coderdk Praktikant
01. juli 2005 - 03:00 #9
Øhm nej, så skal der jo stå ftp://1.2.3.4/public_html/uploads/ :)
Avatar billede kgp43 Nybegynder
01. juli 2005 - 10:59 #10
ftp://1.2.3.4/uploads/

Er dét det samme som '/home/username/uploads'? (<-her ligger min mappe)
Eller er det '/home/username/public_html/uploads'?

Ved phpftp skal jeg bruge forskellige "modes" (BINARY, ASCII). Hvis jeg anvender BINARY ved ASCII filetyper så laver den ged i filen. Er dette også tilfældet med curl?
Avatar billede coderdk Praktikant
01. juli 2005 - 16:21 #11
Det er fra hvor du er når du logger ind, tror jeg, hvis du starter i /home/username så kan du bare nøjes med /public_html/uploads (jeg er 98% sikker)...

Til ASCII kan du bruge:

curl_setopt( $ch, CURLOPT_FTPASCII, 1 );
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:13 #12
Kan ikke få det til at virke.
Den kommer ikke med nogen fejl, men uploader intet.

Hvis jeg ændre:
- curl_setopt( $ch, CURLOPT_URL, 'ftp://1.2.3.4/uploads/' . $filnavn );
til:
- curl_setopt( $ch, CURLOPT_URL, 'ftp://1.2.3.4/uploads/' . $fp);

Så uploader en en fil med navnet "(Array)"


--------------

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $filnavn );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );
Avatar billede coderdk Praktikant
02. juli 2005 - 16:16 #13
Ja, $fp er en pointer til en file-resource - det skal jo være filnavnet ;)
Så måske:

curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file]['name'] );
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:21 #14
den ser ud til at virke :)

Nogle tilføjelser:
$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:21 #15
btw, er der en måde hvorpå man kan check om filen er uploaded okay eller poste eventuelle fejlmeddelser?
Avatar billede coderdk Praktikant
02. juli 2005 - 16:24 #16
Yeps, http://dk2.php.net/manual/en/features.file-upload.php
Du kan checke på $_FILES['upld_file']['error'] og filstørrelsen, enten ved file_size eller $_FILES['upld_file']['size']
Avatar billede coderdk Praktikant
02. juli 2005 - 16:24 #17
Smider lige et svar, hvis du bliver tilfreds :)
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:28 #18
Anvender allerede [error] og diverse checks, mangler bare noget der validere at upload var okay.

Før havde jeg noget ala:

- Kan ikke connecte til ftp, "Not able to connect to FTP"
- Fejl i upload, "Error uploading your file"
- Upload okay, "File uploaded without problems"

Er dette muligt med curl?
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:30 #19
noget ala:

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
$upload = curl_exec( $ch );
curl_close( $ch );
fclose( $fp );

if($upload == false) {
echo "Error uploading your file";
}else{
echo "File uploaded";
}

- Ved ikke lige om denne kode er valid
Avatar billede coderdk Praktikant
02. juli 2005 - 16:31 #20
Mjah, jeg ville:

curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

og så:

$result = curl_exec( $ch );

Og så i stedet for curl_close:

if ( curl_errno( $ch ) )
{
  echo 'Fejl ved upload: ' . curl_error( $ch );
}
else
{
  curl_close( $ch );
}

:)
Avatar billede coderdk Praktikant
02. juli 2005 - 16:32 #21
Totale script:

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
$result = curl_exec( $ch );
fclose( $fp );

if ( curl_errno( $ch ) )
{
  echo 'Fejl ved upload: ' . curl_error( $ch );
}
else
{
  curl_close( $ch );
}

Muligvis skal IF'en være:

if ( curl_errno( $ch ) || strlen( $result ) > 0 )
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:36 #22
Prøver mig lidt frem :)
Kan curl uploade store filer (60MB) som standard?
Avatar billede coderdk Praktikant
02. juli 2005 - 16:37 #23
Ja, det skulle jeg da mene, husk dog set_time_limit( 0 ); så scriptet ikke timer ud :)
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:39 #24
Kan ikke få nogle af de to til "if's" til at virke.
Prøver at søge lidt på google.
Avatar billede coderdk Praktikant
02. juli 2005 - 16:41 #25
Prøv:

if ( curl_errno( $ch ) != 0 )

Eller:

if ( curl_errno( $ch ) != 0 || strlen( $result ) > 0 )

Evt. lige se hvad $result indeholder ;)
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:43 #26
hvad skal dette bruges til:
CURLE_COULDNT_CONNECT
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:43 #27
den vil jeg lige prøve :)
Avatar billede kgp43 Nybegynder
02. juli 2005 - 16:57 #28
Kom til at kludre lidt rundt i det tidligere, men dette her ser ud til at virke.
$reult har værdien "1" ved success og er tom ved fejl.

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
$result = curl_exec( $ch );
curl_close( $ch );

if($result != 1 ) {
  echo 'Fejl ved upload: ' . curl_error( $ch );
}else{
  echo "Success";
  curl_close($ch);
}
Avatar billede kgp43 Nybegynder
02. juli 2005 - 17:22 #29
Har et problem med at uploade ASCII filer ved brug af dit forslag ovenfor.

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_FTPASCII, 1 );
$result = curl_exec( $ch );
curl_close( $ch );
fclose( $fp );

if($result != 1 ) {

    echo "Error uploading your file using ASCII mode";
   
}else{

    echo "File uploaded using ASCII mode";

}
Avatar billede kgp43 Nybegynder
02. juli 2005 - 18:25 #30
typisk.

Har endelig fået det til at virke, men filstørrelsen på store filer (30-60MB) er 0 byte efter upload, hvor den er korrekt ved mindre filer (op til 3MB).
Avatar billede kgp43 Nybegynder
02. juli 2005 - 18:32 #31
(se forrige post)

Min kode:
$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://' . $server_ip . '/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
$result = curl_exec( $ch );
curl_close( $ch );
fclose( $fp );
Avatar billede coderdk Praktikant
02. juli 2005 - 19:12 #32
Weird - Prøv uden curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] );
Avatar billede kgp43 Nybegynder
02. juli 2005 - 19:39 #33
Har netop uploaded en 3.6MB fil men den flyder kun 2.9MB efter upload (zip).
Downloadede filen men den fylder stadig kun 2.9MB.

Den kommer med en fejl når jeg prøver at pakke den ud, hvor den originale version er okay. Der ud til at upload processen ødelægger data i filen.
Avatar billede kgp43 Nybegynder
02. juli 2005 - 19:48 #34
... og det var uden "curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] )"
Avatar billede coderdk Praktikant
02. juli 2005 - 19:56 #35
Du har ikke sat curl_setopt( $ch, CURLOPT_FTPASCII, 1 ); til ?
Måske skal den være 0?
curl_setopt( $ch, CURLOPT_FTPASCII, 0 ); ?
Avatar billede kgp43 Nybegynder
02. juli 2005 - 20:54 #36
Når jeg ændre til 0 så vil den ikke uploade
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester