WinFuture-Forum.de: Downloaden Einer Datei über Php - Auch Sehr Große Dateien - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Downloaden Einer Datei über Php - Auch Sehr Große Dateien


#1 Mitglied ist offline   Meatwad 

  • Gruppe: aktive Mitglieder
  • Beiträge: 784
  • Beigetreten: 07. August 04
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Bad Vilbel
  • Interessen:Computer, Inliner, Chatten...

geschrieben 07. Oktober 2006 - 14:24

hallo,
ich habe ein downloadscirpt mit rechemanagement geschrieben. Wenn eine datei downgeloaded werden soll, wird sie per file_get_contents() geladen und dann ausgegeben. ich habe bereits dashier hinzugefügt:
@ini_set('memory_limit','1024M');

aber dann können nur dateien bis 1GB geladen werden. wenn ich den wert größer mache, wird der ram total überladen, das will ich auhcnicht. was kann ich tuhen, damit wesentlich größere daetien (bis zu 10gb) geladen werden können?


danke
Meatwad

Dieser Beitrag wurde von Meatwad bearbeitet: 07. Oktober 2006 - 14:24

I am away to look for my self. If I am back before I return keep me here. | Mein Server
0

Anzeige



#2 Mitglied ist offline   [Elite-|-Killer] 

  • Gruppe: aktive Mitglieder
  • Beiträge: 762
  • Beigetreten: 02. Oktober 05
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Passau

geschrieben 07. Oktober 2006 - 18:31

Bei diesen Großen Dateimengen würde sich ein geteiltes Archiv meiner Meinung nach fast anbieten.
0

#3 Mitglied ist offline   hasch 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.790
  • Beigetreten: 28. Januar 04
  • Reputation: 0
  • Wohnort:Localhost
  • Interessen:Ach so viele ...

geschrieben 07. Oktober 2006 - 19:57

Vllt. hilft dir meine Idee. Setze einfach per .htaccess einen Zugriffsschutz (mit Passwort und User) und lasse dann im Script den geforderten Namen und Passwort per $_SERVER['PHP_AUTH_USER'] usw. mit den korrekten Daten setzen und dann kannste dein Transfer Limit ja immernoch um die Größe der Datei erhöhen. :8):
0

#4 Mitglied ist offline   asko 

  • Gruppe: aktive Mitglieder
  • Beiträge: 144
  • Beigetreten: 17. November 02
  • Reputation: 0

geschrieben 07. Oktober 2006 - 20:12

Wie bietest Du denn den Download für den User an?
0

#5 Mitglied ist offline   Meatwad 

  • Gruppe: aktive Mitglieder
  • Beiträge: 784
  • Beigetreten: 07. August 04
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Bad Vilbel
  • Interessen:Computer, Inliner, Chatten...

geschrieben 07. Oktober 2006 - 22:41

das script hat für jeden user die rechte für den jeweiligen ordner in einer datenbank gespeichert. die user loggen sich ein und können dann nur die datien downloaden, auf die sie zugriff haben sollen. und in jedes verzecihnis eine htacces rein wär en bissi aufwändig, und nervig. gibts nicht noch andere lösungen? sonst werde ich wohl wirklich geteilte archive nehmen müssen
I am away to look for my self. If I am back before I return keep me here. | Mein Server
0

#6 Mitglied ist offline   asko 

  • Gruppe: aktive Mitglieder
  • Beiträge: 144
  • Beigetreten: 17. November 02
  • Reputation: 0

geschrieben 08. Oktober 2006 - 01:26

Ich meinte eher, ob Du den Download normal als Datei an den Browser schickst oder ob Du die Datei als Stream an den Client schickst. Das "wie" bezog sich also auf die Art, wie Du den download anbietest.

Das Problem das bei Dir entsteht ist, daß Du die Downloadfile mit file_get_contents() einliest. Das liest also die ganze Datei als String ein und muß dementsprechend Speicher reservieren. Wenn Du aber eine Datei direkt als Download senden willst, dann benutzt man i.d.R. eine Header-Anweisung wie etwa diese
<?php
	   header ( "Content-Type: application/octet-stream" );
	   header ( "Content-Length: " . filesize ( $Datei ) );
	   header ( "Content-Disposition: attachment; filename=$DateiName" );
	   readfile ( $Datei );
?>


$Datei ist -logischerweise- die Datei und $DateiName ist der vorgegebene Name unter dem der Download angeboten wird (z.B. irgendwas.zip). Auf diese Weise wird der Download gestreamed und muß nicht komplett in den Speicher geladen werden für die Ausgabe.

Eine Andere Möglichkeit wäre es die Userrechte in die Session zu speichern und in die Ordner eine Index legen in der abgefragt wird ob der User berechtigt ist diesen Ordner zu betreten. Da kannst Du dann auch ganz normal die Dateien zum DL anbieten ohne mit Scripts kämpfen zu müssen.

Da Du die Rechte der User eh schon in der DB hast, würde ich die 2. Methode wählen, weil sie in diesem Fall wohl einfacher umzusetzen ist.

Dieser Beitrag wurde von asko bearbeitet: 08. Oktober 2006 - 01:27

0

#7 Mitglied ist offline   hasch 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.790
  • Beigetreten: 28. Januar 04
  • Reputation: 0
  • Wohnort:Localhost
  • Interessen:Ach so viele ...

geschrieben 08. Oktober 2006 - 08:29

Beitrag anzeigenZitat (Meatwad: 07.10.2006, 23:41)

und in jedes verzecihnis eine htacces rein wär en bissi aufwändig, und nervig.

1. wäre die methode von asko wohl sinnvoller bei deinem problem.
2. wäre ja in jedem verzeichnis die selbe .htaccess datei.
2. könntest du diese ja automatisch beim setzen des ordners mit setzen lassen.
0

#8 Mitglied ist offline   Meatwad 

  • Gruppe: aktive Mitglieder
  • Beiträge: 784
  • Beigetreten: 07. August 04
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Bad Vilbel
  • Interessen:Computer, Inliner, Chatten...

geschrieben 08. Oktober 2006 - 17:06

Beitrag anzeigenZitat (asko: 08.10.2006, 02:26)

Das Problem das bei Dir entsteht ist, daß Du die Downloadfile mit file_get_contents() einliest. Das liest also die ganze Datei als String ein und muß dementsprechend Speicher reservieren. Wenn Du aber eine Datei direkt als Download senden willst, dann benutzt man i.d.R. eine Header-Anweisung wie etwa diese
<?php
	   header ( "Content-Type: application/octet-stream" );
	   header ( "Content-Length: " . filesize ( $Datei ) );
	   header ( "Content-Disposition: attachment; filename=$DateiName" );
	   readfile ( $Datei );
?>


$Datei ist -logischerweise- die Datei und $DateiName ist der vorgegebene Name unter dem der Download angeboten wird (z.B. irgendwas.zip). Auf diese Weise wird der Download gestreamed und muß nicht komplett in den Speicher geladen werden für die Ausgabe.


im moment habe ich das hier als headers reingemacht:
header('Content-type: application/octet-stream');
header('Content-Length: '.$filesize);
header('Content-Disposition: attachment; filename="'.$file2load.'"');

ich denke, dass ich das ganze eifnach wie von dir vorgeschlagen mit readfile mache, und nicht mit file_get_contents(). wird hier nur der teil in den ram geladen, der gerade versendet wird? dass also auch eine 10GB datei nicht mehr als ein paar megabyte im ram auf einmal verbraucht?
I am away to look for my self. If I am back before I return keep me here. | Mein Server
0

#9 Mitglied ist offline   asko 

  • Gruppe: aktive Mitglieder
  • Beiträge: 144
  • Beigetreten: 17. November 02
  • Reputation: 0

geschrieben 08. Oktober 2006 - 18:00

Beitrag anzeigenZitat (Meatwad: 08.10.2006, 18:06)

ich denke, dass ich das ganze eifnach wie von dir vorgeschlagen mit readfile mache, und nicht mit file_get_contents(). wird hier nur der teil in den ram geladen, der gerade versendet wird? dass also auch eine 10GB datei nicht mehr als ein paar megabyte im ram auf einmal verbraucht?


file_get_contents() liest die komplette Datei am Stück als String ein und belegt dementsprechend Speicher.
readfile() merkt sich nur die Zeigerposition an welcher Byte-Position der Download ist. Es werden also auch keine "paar MB" Speicher belegt sondern nur wenige Byte.

Vergleichbar mit einem Buch; wenn Du ein Buch lesen willst und nicht auf einmal schaffst, merkst Du dir doch auch nur die Seitennummer bis wohin Du gekommen bist und behälst nicht den exakten Wortlaut bis zu der Stelle im Kopf bis wohin Du bereits gelesen hast. ... So in etwa könnte man den Unterschied von readfile() und file_get_contents() erklären. :)
0

#10 Mitglied ist offline   Meatwad 

  • Gruppe: aktive Mitglieder
  • Beiträge: 784
  • Beigetreten: 07. August 04
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Bad Vilbel
  • Interessen:Computer, Inliner, Chatten...

geschrieben 08. Oktober 2006 - 18:10

okay, dankeschön! das war die lösung zu meinem problem.


danke nochmals an alle, die mir geholfen haben

MfG
Meatwad
I am away to look for my self. If I am back before I return keep me here. | Mein Server
0

#11 Mitglied ist offline   cinemaxxxxx 

  • Gruppe: Mitglieder
  • Beiträge: 2
  • Beigetreten: 07. Mai 12
  • Reputation: 0
  • Geschlecht:Männlich

geschrieben 08. Mai 2012 - 10:26

Hallo zusammen...

Wie es ausschaut greife ich hier ein relativ altes "Problem" mal wieder auf ;-)

Ich habe ebenfalls eine download.php geschrieben zum Download von idR. recht grossen Files, meistens so 1-2 Gb gross.
Ich habe das ganze ebenfalls mit readfile() gelöst, was auch (bis jetzt) bestens funktioniert hat.

Da ich jedoch in meiner Datenbank (von da beziehe ich auch den Dateinamen) eine Logtabelle führe, wo drin stehen soll wann eine Datei von wem heruntergeladen wurde, habe ich das readfile folgendermassen implementiert:

if (@readfile($fileserver . '/' . $dataset['link_download']) === false) {
	// Update download info in the database
	$sqlinsert  = 'INSERT INTO tb_logs (logtype_id, account_id, data_id)';
	$sqlinsert .= '     VALUES (5, ' . $userid . ', ' . $dataset['clip_id'] . ')';
	mysql_query($sqlinsert, $db_conn);
} else {
	// Update download info in the database
	$sqlinsert  = 'INSERT INTO tb_logs (logtype_id, account_id, data_id)';
	$sqlinsert .= '     VALUES (4, ' . $userid . ', ' . $dataset['clip_id'] . ')';
	mysql_query($sqlinsert, $db_conn);
};



Zur Erklärung: logtype_id = 4 steht für "Download complete", 5 steht für "Download failed", $dataset['clip_id'] ist die ID des Files aus der Tabelle mit allen Filenamen

Wie ich festgestellt habe, trägt das Script die Informationen sauber in die Logtabelle ein NUR SOFERN die Datei nicht "allzu" gross ist.
Z.B. eine Datei von 20Mb grösse lädt er herunter und trägt das ein, eine Datei mit Grösse 540Mb hingegen einfach nicht :-S

Es scheint mir fast so dass er bei grösseren Dateien nach dem Download einfach nicht mehr weiter macht mit dem Script :-(

Hat jemand eine Idee woran das liegen könnte?
Ich weiss langsam keinen Rat mehr.

Liebe Grüsse
Raphael
0

#12 Mitglied ist offline   mephistolino 

  • Gruppe: aktive Mitglieder
  • Beiträge: 469
  • Beigetreten: 17. September 10
  • Reputation: 36
  • Geschlecht:unbekannt

geschrieben 08. Mai 2012 - 11:18

ich bin kein entwickler ("nur" softwaretester ;) ), aber ich würde auf ein timeout tippen.

das würde auch erklären, warum es mit kleinen dateien funktioniert.

schau dir mal max_execution_time an, z.b. hier oder hier
0

#13 Mitglied ist offline   cinemaxxxxx 

  • Gruppe: Mitglieder
  • Beiträge: 2
  • Beigetreten: 07. Mai 12
  • Reputation: 0
  • Geschlecht:Männlich

geschrieben 09. Mai 2012 - 08:57

Ohhh... das hätt ich jetzt nicht gedacht dass es diese Einstellung ist :blink:
Habe es mal ausprobiert und scheinbar klappts damit bestens :)

Vielen Dank für den wertvollen Tip :D

Gruss
Raphael
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0