PHP – Funkce flush a webový štít AVG
Když nefunguje výpis průběhu činnosti na serveru
3. 10. 2012
Normální postup pro vysypání výstupu
Pokud potřebujete během vykonávání PHP skriptu informovat uživatele o aktuálním průběhu,
tzn. zobrazit aktuálně vytvořenou část html stránky už za běhu PHP skriptu a nečekat na jeho dokončení,
můžete na začátek skriptu napsat "ob_implicit_flush();" pro zapnutí automatického výplachu bufferu,
a pak v každém místě, kde chcete uživateli zobrazit doposud vytvořenou část stránky
(typicky to může být uvnitř for cyklu nebo foreach cyklu, ale klidně i jinde)
použijete flush(); nebo ob_flush();.
Anebo použijete některou jinou variantu na téma funkce flush()…
více o tom naleznete v článku Jakuba Vrány nebo v manuálu PHP .
Problém s AVG – flush nefunguje
Může ale nastat zrada – PHP funkce flush() nefunguje – vypíše se až celá stránka, po dokončení skriptu.
Pokud uživatel používá antivir AVG a v jeho komponentě LinkScanner má zapnutý Webový štít,
může webový štít průběžně posílaný html kód zadržovat ve svém zásobníku,
a prohlížeči poslat až celou html stránku najednou. Což jako autoři kódu v danou chvíli nechceme.
Co s tím?
Zjistil jsem, že na stejném počítači, kde AVG zadržuje průběžně posílaný HTML kód,
mi flush funguje u stránky, kde postupně vypisuji tabulku se stovkami řádků, z nichž každý obsahuje vícero údajů.
Řešení
I zkusil jsem tedy poslat do průběžně doplňované, leč AVGčkem zadržované, stránky větší množství jalového komentáře v HTML kódu.
A ono to pomohlo. Je tedy třeba AVGčku HTML kódem dostatečně naplnit zásobník, aby kód poslalo prohlížeči hned, a nečekalo až na konec stránky.
Konkrétně před flush umístit např. tento kód:
for ($j=1; $j<30; $j++) echo "<!-- balast pro zvětšení zdrojáku kvůli flush a avg-->";
(Pro počítání průběhů cyklu tu používám proměnnou $j,
protože je docela možné, že tento kód bude umístěn v cyklu,
pro jehož řízení už je typický název indexu $i použit.)
Když to nepomůže, nastavte počet cyklů na 300, 3000, 30000, … potřebný počet cyklů záleží na konkrétní situaci.
Řešení je to sice dosti nečisté, ba řekl bych až nouzové,
protože nepěkně zatěžuje přenosovou síť i operační paměť,
ale je jediné, které jsem vymyslel.
A funguje. A když musíš, tak musíš.
Poznámka
Při hledání informací o potížích s funkcí funkce flush a jí blízkých jsem narazil na zmínku,že přinejmenším určité verze Opery vyžadují, abyste před použitím funkce flush vypsali tag pro odřádkování "<br />".