Uso correcto del Buffer de Salida

2 feb 2012, 19:37:19
Vistas: 21.1K
Votos: 6

Estoy intentando usar acciones para sobrescribir llamadas a funciones que actualmente tengo en una plantilla (para facilitar la actualización de ciertas secciones replicadas). Por ejemplo, en archives.php tengo lo siguiente:

<?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(__('Archivos Diarios: %s', 'roots'), get_the_date());
            } elseif (is_month()) {
                printf(__('Archivos Mensuales: %s', 'roots'), get_the_date('F Y'));
            } elseif (is_year()) {
                printf(__('Archivos Anuales: %s', 'roots'), get_the_date('Y'));
            } elseif (is_author()) {
                global $post;
                $author_id = $post->post_author;
                printf(__('Archivos del Autor: %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(); ?>

Puedes ver algunas de las funciones, como roots_content_before(); En un archivo separado, tengo lo siguiente:

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

y lo uso así:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ?>

        este es un texto de ejemplo

    <?php }

?>

Por lo que he leído, especialmente si voy a tener grandes bloques de código, debería estar usando el buffer de salida, pero cuando intento hacer esto, no obtengo absolutamente nada:

<?php

    add_action('roots_content_before', 'roots_bootstrap_content_before');

    function roots_bootstrap_content_before() { ob_start(); ?> 

        este es un texto de ejemplo

       <?php return ob_get_clean();

    }

?>

¿Estoy pensando en esto completamente mal? Todavía estoy aprendiendo, pero he estado intentándolo durante un tiempo sin ningún éxito. Cualquier orientación en la dirección correcta sería realmente apreciada. ¡Gracias!

0
Todas las respuestas a la pregunta 2
9
13

No, no necesitas el buffer de salida en este caso. Como regla general: No uses el buffer de salida a menos que realmente sea necesario.

Imagina lo que sucede si alguien más también utiliza el buffer de salida desde un plugin y se cruza con el tuyo:

// plugin
ob_start();

// más tarde, tú en tu tema
ob_start();

// llamas a una función donde el autor del plugin enganchó para llamar:
print ob_get_clean();

// llamas al *tuyo*:
return ob_get_clean();

// ¡está vacío!

Esto es realmente difícil de depurar. Evítalo.


No necesitas una función separada para cubrir un simple do_action(). Simplemente escribe do_action('roots_content_before'); en tu tema.

2 feb 2012 19:55:08
Comentarios

Estoy de acuerdo con toscho aquí. No uses el almacenamiento en búfer de salida. Utiliza las llamadas a acciones y filtros donde sea necesario.

Scott Scott
2 feb 2012 20:11:37

Hola @toscho, realmente agradezco tu aporte. Recién había comenzado a leer sobre el almacenamiento en búfer de salida, pero según ese artículo, parecía que había un aumento en el rendimiento. Ya sea que realmente lo haya o no, casi suena como que si tienes el control completo de la aplicación sería bueno, pero como WordPress tiene miles de plugins, podrías estar pidiendo problemas ;) ¡Gracias de nuevo!

Zach Zach
2 feb 2012 21:19:52

@Zach Este artículo está equivocado desde la primera línea. :) Envía tu salida al usuario lo antes posible. En temas con código de trabajo largo, incluso llamo a flush() antes y después del código lento para acelerar el renderizado.

fuxia fuxia
2 feb 2012 22:05:30

¡Los cabrones! ;)

Aprecio la información adicional sobre eso @toscho

Zach Zach
3 feb 2012 22:29:59

Renderizado progresivo mediante múltiples flushes es una buena lectura.

fuxia fuxia
3 feb 2012 22:32:39

toscho, puedes tener buffers de salida anidados. Aunque no es bueno perder el control sobre ellos :)

offroff offroff
11 abr 2012 09:58:07

@offroff En WP alguien más podría agregar un anidamiento no deseado. Por lo tanto, no lo uses en plugins o temas.

fuxia fuxia
11 abr 2012 13:37:43

Esta respuesta es un poco engañosa. Ignora situaciones en las que puedes usar OB sin problemas. Por ejemplo, tienes una función que imprime algo de HTML y quieres devolver ese HTML. Mientras no ejecutes acciones comunes o llames a funciones de WP como get_header() en ella, deberías usar OB para producir un código más legible.

onetrickpony onetrickpony
16 may 2012 22:26:48

@OneTrickPony Dependiendo de las operaciones exactas que ejecutes, podrías alcanzar antes el límite de memoria con el almacenamiento en búfer de salida porque... bueno... todo se almacena en memoria hasta que se llama a ob_end_clean(). Si realmente lo necesitas, úsalo. Eso es lo que dije en mi respuesta. :)

fuxia fuxia
16 may 2012 22:52:11
Mostrar los 4 comentarios restantes
3

La respuesta de @toscho es completamente incorrecta.

12 mar 2015 18:20:23
Comentarios

Esto es un poco duro. Creo que lo que @toscho intentó decir no es que no puedas anidar, sino que si por alguna razón llamas a ob_get_clean() antes de que el código de, por ejemplo, otro plugin que inició el primer ob_start() llame a ob_get_clean(), obtendrás resultados inesperados. Simplemente advierte que solo deberías usarlo si no hay otra manera, ya que hay desventajas que podrías no notar al principio.

kraftner kraftner
12 mar 2015 18:43:49

¿Viste el segundo enlace? Hay un manejo agradable que aborda exactamente el problema de esta pregunta. No hay nada inesperado al anidar; pruébalo tú mismo: 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

Para ser honesto, no lo hice. De nuevo, todo lo que digo es que hay muchas maneras de arruinar esto, así que es mejor usarlo solo cuando no hay otra alternativa. Como nota al margen: esta es exactamente la razón por la que las respuestas que solo contienen enlaces son mal vistas aquí. Si hubieras añadido la esencia de tus enlaces a la respuesta, eso habría ayudado mucho.

kraftner kraftner
13 mar 2015 11:45:07