2010-08-13 11 views
7

Pracuję nad skryptem PHP, który generuje duże (multi-MB) dane wyjściowe w locie, bez znajomości długości z góry. Piszę bezpośrednio do php://output przez fwrite() i próbowałem zarówno standardowe wyjście i przy użyciu Transfer-Encoding: chunked (kodowanie porcji w razie potrzeby), ale bez względu na to, co próbuję przeglądarka czeka aż wszystkie dane są zapisywane przed wyświetleniem okna pobierania. Próbowałem też po nagłówkach i po każdym kawałku, ale to też nie robi różnicy.Buforowanie wyjściowe Apache/PHP

Zgaduję, że Apache buforuje dane wyjściowe, ponieważ przeglądarka zwykle wyświetla się po otrzymaniu kilku KB z serwera.

Czy ktoś ma jakieś pomysły, jak zatrzymać to buforowanie i przepłukać dane w przeglądarce podczas generowania?

Dzięki, J

+1

Zamiast przypuszczać, że apache nie spłukuje się, dopóki cała zawartość nie zostanie wygenerowana, sugeruję użycie wireshark lub podobnych narzędzi, aby zobaczyć, jakie dane są wysyłane do przeglądarki. Wstaw trochę wywołań "uśpienia (1)", jeśli chcesz spowolnić działanie. (Wątpię, czy Apache utrzymuje kilka megabajtów na jednym gnieździe przed opróżnieniem buforów.) – sarnold

+3

Domyślam się, że masz włączoną kompresję GZIP w konfiguracji php.ini i/lub apache. W tym przypadku apache zawsze buforuje. Nie znalazłem sposobu, aby tego uniknąć (poza wyłączaniem kompresji), więc zobaczmy, co inni o tym wiedzą. Może to być pytanie dla serverfault.com, ale ... – BlaM

+0

@sarnold - Kiedy mówię, że zgaduję, to jest wyedukowane przypuszczenie, ponieważ śledziłem żądanie przez Fiddlera i nie widzę żadnej odpowiedzi, dopóki nie pojawi się okno pobierania więc jestem całkiem pewny, że buforuje po stronie serwera. @BlaM - Masz całkowitą rację mówiąc, że GZIP jest włączony, nie myślałem o tym jako o możliwej przyczynie, ponieważ jest to kompresja strumieniowa, ale to może być problem. Spróbuję wyłączyć ten skrypt i sprawdzić, co się stanie. Dzięki. – JWood

Odpowiedz

1

Przede wszystkim, jak blam wymienione w swoim komentarzu, jeśli w OutputBuffering konfiguracji PHP jest włączona, to przyzwyczajenie praca, więc dobrze byłoby znać swój phpinfo().

Następną rzeczą, spróbuj, czy działa z dużym plikiem, który jest przechowywany na serwerze WWW, czy wypakowuje plik readfile. I razem z tym sprawdź, czy wysyłasz poprawne nagłówki. Wskazówki dotyczące sposobu readfile() i przesłać odpowiednie nagłówki zapewniono tutaj: StackOverflow: How to force a file download in PHP

A gdy jesteś na to, zadzwoń ob_end_flush() lub ob_end_clean() w górnej części skryptu.