move_uploaded_file failes with large files

Alles, was PHP betrifft, kann hier besprochen werden.

move_uploaded_file failes with large files

Postby kschroeder » 25. February 2015 15:15

Hi,

I have a small internal webpage (running on my own server) to enable users to upload large files.
As long as the file is not larger than 1GB everything works fine.
With larger files the function move_uploaded_file returns FALSE.
Unfortunately I don't get a clue for the reason. No error message in error logs of apache or php. Neither a warning message.
What could be the reason for that limitation?

Here's what I set in php.ini (only relevant entries):
max_execution_time=1200
max_input_time=60
memory_limit=-1
error_reporting=E_ALL
display_errors=On
log_errors=On
report_memleaks=On
track_errors=On
file_uploads=On
upload_max_filesize=5120M
max_file_uploads=50

The apache config is mainly default from xampp, but only ssl connections are supported, ssl certificate is properly installed.
Version xampp-win32-5.6.3-0-VC11

Here's the upload scipt:

Code: Select all
   if (file_exists("/upload/files/") && is_writable("/upload/files/")) {
      for ($i = 0; $i < $num_uploads; $i++) {
         $xfile = "fileupload".$i;
         $name = basename($_FILES[$xfile]['name']);
         $filename = "/upload/files/".$name;
         $tmpname = $_FILES[$xfile]['tmp_name'];
         $success = move_uploaded_file($tmpname, $filename);
         if (!$success) {
            echo "Warning! Error uploading file <br/> $tmpname <br/> $filename <br/>";
            exit;
         }
      }
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 25. February 2015 16:09

First of all: uploading big files with HTTP Forms is a bad idea, you should provide a FTP Server instead.

Maybe there is a timeout, or any size restriction is busted (you only mentioned upload_max_filesize in your post, but there is also a max_post_size restriction in php.ini, maybe this is limited to 1GB), finally there may be an variable MAX_FILE_SIZE in your upload form (which is ignored by some browser, others do not ignore it) etc.

Uploading large files with Apache/PHP takes many ressources from your server and usually results in extremely long HTTP requests, whereas HTTP is designed for quick requests.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby kschroeder » 25. February 2015 16:25

Yes, I forgot to mention this
post_max_size=0

Maybe I have to mention too:
always_populate_raw_post_data = -1

And the http formular:
<form name="upload" enctype="multipart/form-data" method="post">
<input type="hidden" name="<? echo ini_get("session.upload_progress.name"); ?>" value="upload" />
<input type="hidden" name="MAX_FILE_SIZE" value="5120000" />
<label for="fileupload">Select file(s):</label>
<input type="file" id="fileupload" name="fileupload" size="30" required="required" multiple onchange="fileChange();" />
<br/>
<input class="button" type="button" value="Start upload" onClick="fileUpload();" />
</form>


And the javascript part to send ajax request:

Code: Select all
   try{
      req.open('post', url, true);
      req.send(formdaten);
   }catch(err){
      document.getElementById("result").innerHTML = "<div class=\"error\">Error: "+err.description+"</div>";
   }


Nowhere an error message, just the php function move_uploaded_file returns FALSE, that's all I get.
I though about os limitations on windows server 2008 R2 but there are no folder size restrictions or whatever.
Event protocol is empty too.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 25. February 2015 20:35

><input type="hidden" name="MAX_FILE_SIZE" value="5120000" />

You see that?

Anyway - i dont care for that, ruthless. Its simply wrong to upload such big files via HTTP.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby kschroeder » 26. February 2015 08:02

As you said, it's sometimes ignored by some browsers, some not.
But the MAX_FILE_SIZE is set to 5GB which should be much more than 1GB.
Anyway, I did not ask for alternatives or philosophical discussions, I want to know why there's an apparent limitation at 1GB although everything is set to 5GB or unlimited.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 26. February 2015 13:09

kschroeder wrote:But the MAX_FILE_SIZE is set to 5GB which should be much more than 1GB.


The value in your Form shows up only 5MB (not GB).

kschroeder wrote: I want to know why there's an apparent limitation at 1GB although everything is set to 5GB or unlimited.


Because you are overlooking something, i dont know what. Maybe there is a .htaccess which restricts to 1GB, or any function call (ini_set or similar) in a script, or at least another value in the scope of Apache/PHP - somewhere something.

Why do you ask in english in the german board, where the english board is in the bottom of this forum??
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby cmb69 » 27. February 2015 01:25

kschroeder wrote:Anyway, I did not ask for alternatives or philosophical discussions, I want to know why there's an apparent limitation at 1GB although everything is set to 5GB or unlimited.

Abgesehen davon was Nobbie schon angemerkt hat, kommt es vielleicht auch zu einem Timeout. Im Zweifel könntest Du prüfen, ob die Grenze wirklich 1GB ist, oder nicht eher ungefähr 1GB.

Da Du nicht an "Alternativen oder philosophischen Diskussionen" interessiert bist, erspare ich mir Ausführungen zur Fraglichkeit von GB großen Uploads, die bei "langsamen" Verbindungen Stunden dauern können, und das ohne weitere Rückmeldung (falls man nicht explizit dafür sorgt).

kschroeder wrote:Nowhere an error message, just the php function move_uploaded_file returns FALSE, that's all I get.

Prüfst Du auch die Upload-Fehlermeldungen ($_FILES[...]['error'])?

kschroeder wrote:
Code: Select all
if (file_exists("/upload/files/") && is_writable("/upload/files/")) {

Am Rande erwähnt: is_writable() gibt FALSE zurück, wenn die Datei nicht existiert.
User avatar
cmb69
 
Posts: 24
Joined: 18. October 2012 03:09
Location: Germany
XAMPP version: various
Operating System: Windows 10

Re: move_uploaded_file failes with large files

Postby kschroeder » 27. February 2015 10:36

cmb69 wrote:Da Du nicht an "Alternativen oder philosophischen Diskussionen" interessiert bist, erspare ich mir Ausführungen zur Fraglichkeit von GB großen Uploads, die bei "langsamen" Verbindungen Stunden dauern können, und das ohne weitere Rückmeldung (falls man nicht explizit dafür sorgt).

Um langsame Verbindungen mache ich mir wenig Sorgen. Der Upload erfolgt ausschließlich aus dem internen Netz, Anbindung mind. 100Mbit.
cmb69 wrote:
kschroeder wrote:
Code: Select all
if (file_exists("/upload/files/") && is_writable("/upload/files/")) {

Am Rande erwähnt: is_writable() gibt FALSE zurück, wenn die Datei nicht existiert.

Dann mache ich hier doch schonmal nichts falsch. Ich prüfe, ob das Verzeichnis existiert und das Script die benötigten Schreibrechte hat.
Theoretisch ist die Abfrage eher überflüssig, da ich normalerweise sicherstellen kann, dass das Verzeichnis immer existieren wird und die Rechte sich nie ändern.
Die Prüfung hatte ich eingebaut, um etwaige dieser Form Probleme 100%ig auszuschließen.

Ich habe auch die beide Versionen mit dem
Code: Select all
<input type="hidden" name="MAX_FILE_SIZE" value="5120000000" />

und einmal komplett ohne probiert. Auch keine Änderung.
cmb69 wrote:Prüfst Du auch die Upload-Fehlermeldungen ($_FILES[...]['error'])?

Ups, hier wird tatsächlich als Error "1" zurückgegeben, was theoretisch auf "upload_max_filesize" zu klein hinweisen soll.
Aber in der php.ini steht
Code: Select all
upload_max_filesize=5G

Ich hatte es aber auch schon mit
Code: Select all
upload_max_filesize=5120M
versucht. Ohne Erfolg.

Ich habe auch an jeder Stelle (im Formular-Script und im Upload-Script) ein
Code: Select all
ini_set('upload_max_filesize', '5G');
eingetragen.
Auch ohne Erfolg.
Laut Kurzschreibweise soll 5G (oder auch 5g) funktionieren.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 27. February 2015 12:23

Erst mal würde ich einen phpinfo() in dem Verzeichnis absetzen, ob lokal andere Werte gesetzt sind als php.ini

Zweitens würde ich ini_set() auch abfangen, ob es überhaupt gut gegangen ist (ini_set() gibt einen Wert zurück)

Und last not least würde ich im Empfangsscript einen ini_get() machen (ruhig auf mehrere Variablen), ob sie dort den erwarteten Wert haben. Oder gleich einen kompletten phpinfo().
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby kschroeder » 27. February 2015 13:30

Wenn ich im selben Verzeichnis vom upload-Script phpinfo() absetze, erhalte ich die erwarteten Werte.
Code: Select all
ini_set('upload_max_filesize', '5G');

gibt FALSE zurück,aber ein
Code: Select all
echo "--".ini_get('upload_max_filesize')."--<br/>";

gibt "--5G--" zurück.
Also kann ich den Wert wohl nicht setzen, aber er steht richtig drin.
Auch post_max_size und max_execution_time haben die Werte, die auch in der php.ini stehen.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 27. February 2015 21:54

Dann musst Du weitersuchen, ich bin ehrlich, mir ist das wirklich egal. Schlechte Lösungen interessieren mich nicht sonderlich.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby cmb69 » 28. February 2015 01:09

kschroeder wrote:
cmb69 wrote:Prüfst Du auch die Upload-Fehlermeldungen ($_FILES[...]['error'])?

Ups, hier wird tatsächlich als Error "1" zurückgegeben, was theoretisch auf "upload_max_filesize" zu klein hinweisen soll.
Aber in der php.ini steht
Code: Select all
upload_max_filesize=5G

Spontaner Gedanke: wenn Du eine 32bit Version von PHP verwendest, dann sind 5 GB wohl einfach zu viel; die maximale Größe einer Datei müsste dann eigentlich bei etwa 2 GB liegen (2**31-1 Byte). Ich habe bisher nicht mit annähernd so großen Dateien unter PHP zu tun gehabt. Aber gerade mal eine Datei geprüft, die bei `dir` eine Größe von 5.846.456.320 Byte angibt, wird unter 32bit PHP mit filesize() 1.551.489.024 angegeben. Würde mich nicht wundern, wenn es bei Dir ein ähnliches Problem gibt.
User avatar
cmb69
 
Posts: 24
Joined: 18. October 2012 03:09
Location: Germany
XAMPP version: various
Operating System: Windows 10

Re: move_uploaded_file failes with large files

Postby Nobbie » 28. February 2015 12:17

cmb69 wrote:Spontaner Gedanke: wenn Du eine 32bit Version von PHP verwendest, dann sind 5 GB wohl einfach zu viel; die maximale Größe einer Datei müsste dann eigentlich bei etwa 2 GB liegen (2**31-1 Byte).


Das ist eine gute Idee -- und wahrscheinlich liegt das Limit bei 2^32 (weil es unsigned int ist), macht 4GB und beim Versuch, 5GB intern darzustellen werden die Bits abgehackt resp. "modulo 4GB" gerechnet - macht 1GB. Möglich wäre das zumindest, ich habe ehrlich gesagt noch nie probiert, was eigentlich passiert, wenn man so etwas großes einsetzt.

Zweite Möglichkeit: das Zielverzeichnis ist ein FAT32 Laufwerk und erlaubt auch nur max. 4GB, möglicherweise versucht PHP einen Platz von 5GB zu reservieren, was mit ähnlicher Logik wie oben scheitert. Um auf der sicheren Seite zu sein, würde ich also mal nur 1.5GB versuchen. Oder 2GB müßte eigentlich auch gehen.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: move_uploaded_file failes with large files

Postby kschroeder » 02. March 2015 06:55

An die Möglichkeit hatte ich auch schon gedacht, aber relativ schnell wieder verworfen, da die Grenze eben nicht erst bei 2GB erreicht wird, sondern schon bei einer Datei mit 1,3GB.
Ich hatte es auch irgendwann ganz zu Anfang mal geschafft, eine 3,7GB Datei hochzuladen. Naja, sie lag zumindest nachher im upload-Ordner. Da hatte das Script noch ganz andere Schwächen :wink:
Ich habe aber leider auch keine Idee, was sich geändert hat, dass es jetzt nicht mehr funktioniert.
kschroeder
 
Posts: 254
Joined: 11. May 2007 13:33

Re: move_uploaded_file failes with large files

Postby Nobbie » 02. March 2015 11:14

Trotzdem würde ich die "5G" da rausnehmen, wie soll ein 32bit integer (und irgendwann muss PHP den Wert umwandeln) größer als 5G sein? Probiere es wenigstens mal aus, da 2GB zu setzen. Gibt es da eigentlich nicht die Möglichkeit, 0 zu setzen (so ähnlich wie bei den Timeouts, die damit deaktiviert werden). In der Doku steht dazu nichts.

Es ist und bleibt Krampf, vor allem wenn Du sagst, dass Du eh nur im LAN die Dateien herumschiebst, auch da ist ein FTP Server oder eine Windows Freigabe definitiv überlegen, PHP und HTTP sind nun einmal nicht für so große Uploads konzipiert. Und im WWW läuft das sowieso nicht, so ein Upoad dauert ja mehrere Stunden.

Vielleicht scheitert es ja auch am AJAX?!
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Next

Return to PHP

Who is online

Users browsing this forum: No registered users and 19 guests