Uso corretto del Buffer di Output

2 feb 2012, 19:37:19
Visualizzazioni: 21.1K
Voti: 6

Sto cercando di utilizzare le actions per sovrascrivere le chiamate alle funzioni che ho attualmente in un template (per rendere più facile l'aggiornamento di determinate sezioni replicate). Per esempio, in archives.php ho quanto segue:

<?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(__('Archivi Giornalieri: %s', 'roots'), get_the_date());
            } elseif (is_month()) {
                printf(__('Archivi Mensili: %s', 'roots'), get_the_date('F Y'));
            } elseif (is_year()) {
                printf(__('Archivi Annuali: %s', 'roots'), get_the_date('Y'));
            } elseif (is_author()) {
                global $post;
                $author_id = $post->post_author;
                printf(__('Archivi Autore: %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(); ?>

Puoi vedere alcune delle funzioni, come roots_content_before(); In un file separato, ho quanto segue:

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

e lo uso così:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ?>

        questo è del testo

    <?php }

?>

Da quello che ho letto, specialmente se avrò grandi blocchi di codice, dovrei utilizzare il buffer di output, ma quando provo a farlo, non ottengo assolutamente nulla:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ob_start(); ?> 

        questo è del testo

       <?php return ob_get_clean();

    }

?>

Sto pensando a questo in modo completamente sbagliato? Sto ancora imparando, ma ci sto provando da un po' senza alcun successo. Qualsiasi indicazione nella giusta direzione sarebbe molto apprezzata. Grazie!

0
Tutte le risposte alla domanda 2
9
13

No, non è necessario utilizzare il buffering dell'output in questo caso. Come regola generale: non usare il buffering dell'output a meno che non sia strettamente necessario.

Immagina cosa succede se qualcun altro utilizza il buffering dell'output anche da un plugin e si incrocia con il tuo:

// plugin
ob_start();

// più tardi, tu nel tuo tema
ob_start();

// chiami una funzione in cui l'autore del plugin ha agganciato per chiamare:
print ob_get_clean();

// tu chiami il *tuo*:
return ob_get_clean();

// è vuoto!

Questo è davvero difficile da debugare. Evitalo.


Non hai bisogno di una funzione separata per coprire un semplice do_action(). Scrivi semplicemente do_action('roots_content_before'); nel tuo tema.

2 feb 2012 19:55:08
Commenti

Concordo con toscho qui. Non usare l'Output Buffering. Usa le chiamate ad action e filter dove necessario.

Scott Scott
2 feb 2012 20:11:37

Ciao @toscho apprezzo molto il tuo contributo. Avevo appena iniziato a leggere riguardo all'output buffering, ma da quell'articolo sembrava ci fosse un aumento di performance. Che ci sia o meno, sembra quasi che se hai il controllo completo dell'applicazione potrebbe essere utile, ma dato che WordPress ha migliaia di plugin, potresti solo chiedere guai ;) Grazie ancora!

Zach Zach
2 feb 2012 21:19:52

@Zach Questo articolo è sbagliato già dalla prima riga. :) Invia il tuo output all'utente il prima possibile. Nei temi con codice che richiede molto tempo, io chiamo addirittura flush() prima e dopo il codice lento per velocizzare il rendering.

fuxia fuxia
2 feb 2012 22:05:30

Quei bastardi! ;)

Apprezzo l'ulteriore approfondimento su questo @toscho

Zach Zach
3 feb 2012 22:29:59

Rendering progressivo tramite multipli flush è una buona lettura.

fuxia fuxia
3 feb 2012 22:32:39

toscho, puoi avere buffer di output annidati. Non è una buona cosa perdere il controllo però :)

offroff offroff
11 apr 2012 09:58:07

@offroff In WP qualcun altro potrebbe aggiungere un annidamento indesiderato. Pertanto, non utilizzarlo in plugin o temi.

fuxia fuxia
11 apr 2012 13:37:43

Questa risposta è un po' fuorviante. Ignora situazioni in cui puoi usare OB senza problemi. Ad esempio, hai una funzione che restituisce dell'HTML e vuoi ritornare quell'HTML. Finché non attivi azioni comuni o non chiami funzioni WP come get_header() al suo interno, dovresti usare OB per produrre codice più leggibile.

onetrickpony onetrickpony
16 mag 2012 22:26:48

@OneTrickPony A seconda delle operazioni esatte eseguite, potresti raggiungere prima il limite di memoria con l'output buffering perché... beh... tutto viene memorizzato in memoria finché non viene chiamato ob_end_clean(). Se davvero ne hai bisogno – usalo. Questo è quello che ho detto nella mia risposta. :)

fuxia fuxia
16 mag 2012 22:52:11
Mostra i restanti 4 commenti
3

La risposta di @toscho è completamente sbagliata.

12 mar 2015 18:20:23
Commenti

Questo è un po' duro. Penso che quello che @toscho voleva dire non è che non si possa annidare, ma che se per qualche motivo chiami ob_get_clean() prima che il codice di un altro plugin che ha avviato il primo ob_start() chiami ob_get_clean(), otterrai risultati inaspettati. Sta solo avvertendo che dovresti usarlo solo se non c'è altro modo, poiché ci sono svantaggi che potresti non notare subito.

kraftner kraftner
12 mar 2015 18:43:49

Hai guardato il secondo link? C'è una bella gestione che affronta esattamente il problema di questa domanda. Non c'è nulla di inaspettato nell'annidamento; provalo tu stesso: 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

Ad essere sincero - no, non l'ho fatto. Ripeto, tutto quello che sto dicendo è che ci sono molti modi per rovinare tutto, quindi è meglio usarlo solo quando non ci sono alternative. Come nota a margine: questo è esattamente il motivo per cui le risposte che contengono solo link non sono ben viste qui. Se avessi aggiunto l'essenza dei tuoi link alla risposta, sarebbe stato molto più utile.

kraftner kraftner
13 mar 2015 11:45:07