Ouput buffering geeft probleem bij export naar Excel

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Nkamp Kamp van de

nkamp Kamp van de

10/11/2017 16:59:55
Quote Anchor link
Hallo,

In werk in een project en daar wordt regelmatig (rapport) data naar Excel geexporteerd. Hiervoor is ooit listxl.php genomen ik geloof van IBM of zo. Dit werkt in zekere mate goed.

Echter er doen zich problemen voor op het moment dat het output buffer bv. nog met scherm meldingen of stukken HTML gevuld staat. Vervolgens kan dan het excel .xml bestand niet meer geopend worden met Excel. Dan treedt de melding "Bestand beschadigd..." op.
En wat ik ook denk nadat de gehele listxl.php is uitgevoerd en ik DENK dat het bestand al is afgesloten/weggeschreven, maar dat is misschien niet correct, want er wordt dan nog wat naar het scherm geschreven en dat zie ik dan ook in het .xml bestand terug zoals <script></script>.


Nadenkend/googlend heb ik dit toegevoegd:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
 ob_end_clean();
 header( "content-type: text/xml" );
 //etc. ...
?>


Nu werkt het maar als ik de uitleg lees " Clean (erase) the output buffer and turn off output buffering", dan vooral het laatste denk ik, is dit wel de juiste oplossing?
Ik weet hier niet de consequentie van en daarom eigenlijk de vraag kan ik dit er maar zo ongestraft tussen plaatsen?

Nico
 
PHP hulp

PHP hulp

26/11/2024 18:45:06
 
Thomas van den Heuvel

Thomas van den Heuvel

10/11/2017 17:31:57
Quote Anchor link
Outputbuffers kun je stapelen, dus mogelijk is dat niet de meest verstandige oplossing. Je website zou ook van output buffering gebruik van kunnen maken. Daarnaast ben je niet echt nagegaan wat nu precies de oorzaak is dat de bestanden "beschadigd" zijn. Waaruit blijkt dit? Je hebt het ook over meldingen, dat duidt mogelijk op fouten / bugs / code die werkt op informatie die er niet is (undefined indexes et cetera). En dat zou weer af kunnen hangen van de data waarmee je de spreadsheet opbouwt, wat er weer voor kan zorgen dat de foutmelding soms optreedt wat het weer moeilijker maakt om de oorzaak (of oorzaken) te localiseren. Ik zou hier nogmaals induiken en dit niet zondermeer onder het tapijt vegen middels het opschonen van de buffer.

Ook heb ik het vermoeden dat je niet ergens de bufferinhoud opslaat (in een variabele)? Ik zou dus eerder een aanroep van ob_get_clean() verwachten in plaats van ob_end_clean() eigenlijk.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

10/11/2017 19:44:48
Quote Anchor link
Als je je php applicatie op de juiste manier opbouwt heb je helemaal geen outputbuffering nodig. Dat is voor mij nog altjd de enigste juiste manier.
 
Thomas van den Heuvel

Thomas van den Heuvel

10/11/2017 23:16:01
Quote Anchor link
Frank Nietbelangrijk op 10/11/2017 19:44:48:
Als je je php applicatie op de juiste manier opbouwt heb je helemaal geen outputbuffering nodig. Dat is voor mij nog altjd de enigste juiste manier.

Meh, niet helemaal mee eens. Het kan handig zijn als je bestanden bakt (XML,CSV etc., eventueel met behulp van templates) waarbij je output buffering gebruikt. Ook kan het de leesbaarheid van je applicatie vergroten omdat je niet eindeloos hoeft te echo'en / quotes hoeft te escapen als je alles binnen PHP probeert te houden.

Ook kan het helpen bij pagina-opbouw, waarbij een stuk functionaliteit op een bepaalde plek in je HTML-document wordt gezet, zoals JavaScript-snippets die je in een footer toevoegt. Bijvoorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
ob_start();
    ?>
<script type="text/javascript">
    //<![CDATA[
        $().ready(function() {
            // ... etc ...
        }); // ready
    //]]>
    </script><?php
$this
->addInlineJs(ob_get_clean());
?>

Lijkt mij een stuk beter leesbaar dan alles echo'en.

EDIT: en dat is dus ook een voorbeeld waarin je dingen niet direct in de goede volgorde kunt zetten, output buffering kan dan uitkomst bieden.
Gewijzigd op 10/11/2017 23:52:59 door Thomas van den Heuvel
 
Ben van Velzen

Ben van Velzen

11/11/2017 00:24:32
Quote Anchor link
+1. Output buffering kan erg zinnig zijn, mits op de juiste manier toegepast. Dus gewoon lekker uitgeschakeld laten in de PHP configuratie zelf, maar zelf aangeven *wanneer* je *wat* wilt bufferen.

Ontopic:
Je kan ook ob_flush gebruiken.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

11/11/2017 01:16:35
Quote Anchor link
>> EDIT: en dat is dus ook een voorbeeld waarin je dingen niet direct in de goede volgorde kunt zetten, output buffering kan dan uitkomst bieden.

Het spijt me Thomas maar ik zou echt niet weten wat ik niet in de goede volgorde kan zetten voor de output. ? !

Toevoeging op 11/11/2017 01:19:48:

p.s. Ik doe ook aan output buffering maar dat heet dan nog variabelen. Met variabelen ben ik nog "in control" maar als de zooi in een output buffer staat dan wordt het wel een heel stukje minder.
 
Thomas van den Heuvel

Thomas van den Heuvel

11/11/2017 03:58:14
Quote Anchor link
Frank Nietbelangrijk op 11/11/2017 01:16:35:
Het spijt me Thomas maar ik zou echt niet weten wat ik niet in de goede volgorde kan zetten voor de output. ? !

Stel dat je een geneste opbouw hebt in pagina-elementen met op het hoogste niveau een "maintemplate". Daarin zitten weer andere stukken functionaliteit, bijvoorbeeld menu's, kleine snippets code en een stuk "hoofdcontent". Dat stuk hoofdcontent wordt éérst "uitgevoerd", omdat die mogelijk aparte javascript- of css-bestanden nodig heeft die in de parent (het maintemplate) ingeladen moet worden. Of dus eerdergenoemde JavaScript snippets die je het liefst net voor de </body> tag wilt zetten (buiten enig ander element). Alle output van dat stuk hoofdcontent wordt in een buffer opgevangen, om vervolgens als de pagina uitgedraaid wordt op de goede plek gezet te worden in het maintemplate.

Dit kun je dus niet lineair doen vanwege de geneste/recursieve opbouw van de content. Elementen uit een lager gelegen niveau bepalen mede het uiterlijk van elementen in een hoger gelegen niveau. Dit zijn in wezen een soort van callbacks.

Het gaat dus verder dan de "variabelen" waar jij het over hebt in die zin dat -om jouw voorbeeld te volgen- het uitvoeren van variabele X van invloed is op de samenstelling van variabele Y.

EDIT: daarnaast buffert PHP van zichzelf al van alles. Dit gebeurt via allerlei interne lagen. Alleen al om die reden zou je, bijvoorbeeld vanuit performanceoverwegingen, output buffering kunnen gebruiken omdat die communicatie dan komt te vervallen / wordt uitgesteld. Tevens kun je met ob_start() een callback-functie definiëren. Een veelgebruikte is ob_gzhandler() die de output tevens comprimeert. Wellicht tegenwoordig een minder belangrijke overweging, maar dit scheelt (op den duur een hoop) bandbreedte.
Gewijzigd op 11/11/2017 15:43:53 door Thomas van den Heuvel
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.