2009-03-16 6 views
3

Ich weiß, dass es möglich ist, aber ich kann es nicht herausfinden.Wie kann man Daten in PHP ohne Inhalt senden?

Ich habe eine MySQL-Abfrage, die ein paar hunderttausend Ergebnisse hat. Ich möchte in der Lage sein, die Ergebnisse zu senden, aber es scheint, die Antwort erfordert Content-Length-Header, um den Download zu starten.

In phpMyAdmin, wenn Sie eine Datenbank exportieren, startet es den Download sofort, FF sagt nur unbekannte Dateigröße, aber es funktioniert. Ich schaute auf diesen Code, konnte es aber nicht herausfinden.

Hilfe?

Danke.

Antwort

9

this document in Abschnitt 14.14 besagt, dass In HTTP, sollte es immer dann, wenn die Länge der Nachricht gesendet werden können, bevor sie übertragen bestimmt werden, sofern dies nicht durch die Regeln in Abschnitt 4.4 verboten ist. Dies bedeutet, dass es nicht gesendet werden muss, wenn Sie nicht sagen können, wie groß es ist.

Senden Sie es einfach nicht.

Wenn Sie Teile der Daten an den Browser senden möchten, bevor alle Daten verfügbar sind, tun Sie flush Ihren Ausgabepuffer? Vielleicht ist das das Problem, nicht das Fehlen eines Headers?

Die Art und Weise bündig verwenden ist wie folgt aus:

  • eine Ausgabe erzeugen, die es in den Puffer es
  • flush() hinzufügen sollten, die an den Client aktuellen Puffer senden soll
  • goto 1

Also, wenn Ihre Abfrage viele Ergebnisse zurückgibt, können Sie nur die Erzeugung Ausgabe für, sagen wir, 100 oder 1000 von ihnen, dann flush, und so weiter.

Um dem Client-Browser mitzuteilen, dass er versuchen soll, eine Datei zu speichern, anstatt sie im Fenster anzuzeigen, können Sie auch den Header Content-disposition: attachment verwenden. Siehe den specification hier, 19.5.1 Abschnitt.

+0

Ich habe die Header, dann habe ich Flush, dann habe ich die SQL-Abfrage. Es erscheint jedoch kein Speicherdialog nach dem Flush. Wenn es sich um eine kleine Datei handelt, erscheint sie nur, wenn die Datei heruntergeladen wurde. Die sql-Abfrage, die ich versuche, dauert 45 Sekunden und hält das Zeitlimit nach dem Senden der Header an. – phazei

+0

angegeben ein bisschen mehr in der anwser – kender

+0

Meine Kopfzeilen: Header ('Content-Type: "'. $ Mime. '"'); header ('Content-Disposition: Anhang; Dateiname =' '. $ Dateiname.' "'); Header ("Content-Transfer-Encoding: Binär"); Header ('läuft ab: 0'); Header ('Pragma: kein Cache'); – phazei

0

Sie müssen kein Content-Length Header-Feld festlegen. Dieses Header-Feld dient nur dazu, dem Client die zu erwartende Datenmenge mitzuteilen. In der Tat kann ein "falscher" Wert dazu führen, dass der Client einige Daten verwirft.

0

Wenn Sie das LiveHTTPHeaders-Plugin in FireFox verwenden, können Sie den Unterschied zwischen den Kopfzeilen, die von phpMyAdmin gesendet werden, und den Kopfzeilen sehen, die von Ihrer Anwendung gesendet werden. Ich weiß nicht genau, was Sie vermissen, aber das sollte Ihnen einen Hinweis geben. Ein Header, den ich sehe, einen schnellen Test auszuführen, ist "Transfer-Encoding: chunked", und ich sehe auch, dass sie keine Inhaltslänge senden. Hier ist ein Link auf das Firefox-Plugin, wenn Sie nicht bereits haben: LiveHTTPHeaders

1

Es ist möglich, dass Sie gzip verwenden, das darauf wartet, dass der gesamte Inhalt generiert wird.Überprüfen Sie Ihre .htaccess für diesbezügliche Anweisungen.

2

Sie können Chunked-Transfer-Codierung verwenden. Im Grunde senden Sie einen Header "Transfer-encoding: chunked", und dann werden die Daten im Chunked-Modus gesendet, was bedeutet, dass Sie die Länge eines Chunks gefolgt von dem Chunk senden. Sie wiederholen dies bis zum Ende der Daten, an dem Sie einen Block mit der Länge null senden.

Details sind in RFC 2616.