Utilizarea corectă a Output Buffer

2 feb. 2012, 19:37:19
Vizualizări: 21.1K
Voturi: 6

Încerc să folosesc acțiuni pentru a suprascrie apelurile de funcții pe care le am în prezent în tot șablonul (pentru a face mai ușoară actualizarea anumitor secțiuni replicate). De exemplu, în archives.php am următoarele:

<?php get_header(); ?>

    <?php roots_content_before(); ?>
    <?php $page_for_posts = get_option( 'page_for_posts' ); if ($page_for_posts) { echo '<h1>' . get_the_title($page_for_posts) . '</h1>'; } ?>
    <h3>
        <?php
            $term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
            if ($term) {
                echo $term->name;
            } elseif (is_day()) {
                printf(__('Arhive zilnice: %s', 'roots'), get_the_date());
            } elseif (is_month()) {
                printf(__('Arhive lunare: %s', 'roots'), get_the_date('F Y'));
            } elseif (is_year()) {
                printf(__('Arhive anuale: %s', 'roots'), get_the_date('Y'));
            } elseif (is_author()) {
                global $post;
                $author_id = $post->post_author;
                printf(__('Arhivele autorului: %s', 'roots'), get_the_author_meta('user_nicename', $author_id));
            } else {
                single_cat_title();
            }
        ?>
    </h3>
    <?php echo category_description(); ?>
    <?php roots_loop_before(); ?>
    <?php get_template_part('loop', 'category'); ?>
    <?php roots_loop_after(); ?>
    <?php roots_content_after(); ?>

<?php get_footer(); ?>

Puteți vedea câteva dintre funcții, cum ar fi roots_content_before(); Într-un fișier separat, am următoarele:

function roots_content_before() { do_action('roots_content_before'); }

și o folosesc astfel:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ?>

        acesta este un text

    <?php }

?>

Din ce am citit, mai ales dacă voi avea bucăți mari de cod, ar trebui să folosesc buffer-ul de ieșire, dar când încerc să fac acest lucru, nu primesc nimic:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ob_start(); ?> 

        acesta este un text

       <?php return ob_get_clean();

    }

?>

Gândesc complet greșit? Încă învăț, dar am încercat de ceva timp fără niciun succes. Orice indiciu în direcția corectă ar fi foarte apreciat. Mulțumesc!

0
Toate răspunsurile la întrebare 2
9
13

Nu, nu ai nevoie de bufferizarea ieșirii în acest caz. Ca regulă generală: Nu folosi bufferizarea ieșirii decât dacă chiar trebuie.

Imaginează-ți ce se întâmplă dacă cineva altcineva folosește și el bufferizarea ieșirii printr-un plugin și se intersectează cu a ta:

// plugin
ob_start();

// mai târziu, tu în tema ta
ob_start();

// apelezi o funcție în care autorul pluginului a adăugat un hook pentru a apela:
print ob_get_clean();

// apelezi *pe a ta*:
return ob_get_clean();

// este gol!

Acest lucru este foarte greu de depanat. Evită-l.


Nu ai nevoie de o funcție separată pentru a acoperi un simplu do_action(). Scrie direct do_action('roots_content_before'); în tema ta.

2 feb. 2012 19:55:08
Comentarii

Sunt de acord cu toscho aici. Nu folosi Output Buffering. Folosește apeluri de acțiuni și filtre acolo unde este nevoie.

Scott Scott
2 feb. 2012 20:11:37

Salut @toscho, apreciez mult feedback-ul. Abia începeam să citesc despre output buffering, dar din acel articol, părea că există o creștere a performanței. Indiferent dacă este sau nu adevărat, se pare că dacă controlezi întreaga aplicație atunci ar fi benefic, dar din moment ce WordPress are mii de plugin-uri, s-ar putea să cauți probleme ;) Mulțumesc din nou!

Zach Zach
2 feb. 2012 21:19:52

@Zach Acest articol este greșit încă de la prima linie. :) Trimite output-ul către utilizator cât mai repede posibil. În teme cu cod care rulează lent, eu chiar apelez flush() înainte și după codul lent pentru a accelera randarea.

fuxia fuxia
2 feb. 2012 22:05:30

Bastarzii! ;)

Apreciez perspectiva suplimentară, @toscho

Zach Zach
3 feb. 2012 22:29:59

Randare progresivă prin multiple flush-uri este o lectură bună.

fuxia fuxia
3 feb. 2012 22:32:39

toscho, poți avea buffere de ieșire imbricate. Nu e bine să pierzi controlul asupra lor totuși :)

offroff offroff
11 apr. 2012 09:58:07

@offroff În WP, altcineva poate adăuga o imbricare nedorită. Prin urmare, nu utilizați acest lucru în plugin-uri sau teme.

fuxia fuxia
11 apr. 2012 13:37:43

Acest răspuns este un pic înșelător. Ignoră situațiile în care puteți folosi OB fără probleme. De exemplu, aveți o funcție care afișează un cod HTML și doriți să returnați acel HTML. Atâta timp cât nu declanșați acțiuni comune sau nu apelați funcții WP precum get_header() în ea, ar trebui să utilizați OB pentru a produce un cod mai lizibil.

onetrickpony onetrickpony
16 mai 2012 22:26:48

@OneTrickPony În funcție de operațiile exacte pe care le executați, puteți atinge mai devreme limita de memorie cu bufferizarea output-ului pentru că... ei bine... totul este stocat în memorie până când este apelată funcția ob_end_clean(). Dacă aveți cu adevărat nevoie - folosiți-o. Asta am spus și în răspunsul meu. :)

fuxia fuxia
16 mai 2012 22:52:11
Arată celelalte 4 comentarii
3

Răspunsul lui @toscho este complet greșit.

12 mar. 2015 18:20:23
Comentarii

Acest lucru este un pic prea dur. Cred că ceea ce a încercat @toscho să spună nu este că nu poți imbrica, ci că dacă din anumite motive apelezi ob_get_clean() înainte ca codul altui plugin, care a inițiat primul ob_start(), să apeleze ob_get_clean(), vei obține rezultate neașteptate. El doar avertizează că ar trebui să folosești această metodă doar dacă nu există altă alternativă, deoarece există dezavantaje care pot să nu fie imediat evidente.

kraftner kraftner
12 mar. 2015 18:43:49

Ai verificat al doilea link? Există o soluție elegantă care abordează exact problema din această întrebare. Nu există nimic neașteptat la imbricare; încearcă singur: ob_start(); echo "0"; ob_start(); echo "a"; echo ob_get_clean(); echo "1"; $a = ob_get_clean(); echo $a;

Robert Robert
12 mar. 2015 19:03:15

Să fiu sincer - nu am făcut-o. Din nou, tot ce spun este că există multe modalități de a da greș cu această abordare, așa că e mai bine să o folosești doar atunci când nu există altă opțiune. Ca observație secundară: Acesta este exact motivul pentru care răspunsurile care conțin doar link-uri nu sunt apreciate aici. Dacă ai fi adăugat esența link-urilor tale în răspuns, asta ar fi fost mult mai util.

kraftner kraftner
13 mar. 2015 11:45:07