Ajax broken by WordPress warnings: solve trough ob_start()?

I am writing a plugin for WordPress. My goal is make it work for everyone. Some pages use ajax responses. Some users have activated the WP_DEBUG constant that shows errors and warnings from themes and other plugins.

This breaks my Ajax PHPs because I include the WordPress Core, and then WP can show warnings in some blogs!

Read More

The old way I solved this, is:

<?php
ob_start();
//The wordpress core require
ob_end_clean();

//Now the ajax response:
echo '0';
?>

However, one user reported a very strange bug: the ajax page never response, only works in Opera, and Google Chrome says: Error 330 (net::ERR_CONTENT_DECODING_FAILED):

Digging in the user web-server, I found that WP configuration, or a plugin or elsewere uses the ob_start(“ob gzhandler”).

The ob_get_status(true) shows in my working webserver:

Array
(
    [0] => Array
        (
            [chunk_size] => 4096
            [type] => 1
            [status] => 0
            [name] => default output handler
            [del] => 1
        )

    [1] => Array
        (
            [chunk_size] => 0
            [size] => 40960
            [block_size] => 10240
            [type] => 1
            [status] => 0
            [name] => default output handler
            [del] => 1
        )

)

And in the buggy web-server:

Array
(
    [0] => Array
        (
            [chunk_size] => 4096
            [type] => 1
            [status] => 0
            [name] => default output handler
            [del] => 1
        )

    [1] => Array
        (
            [chunk_size] => 0
            [size] => 40960
            [block_size] => 10240
            [type] => 1
            [status] => 0
            [name] => default output handler
            [del] => 1
        )

    [2] => Array
        (
            [chunk_size] => 0
            [size] => 40960
            [block_size] => 10240
            [type] => 1
            [status] => 0
            [name] => ob_gzhandler
            [del] => 1
        )

)

The sequence in my user web-server is:

  • My code calls ob_start()
  • Include WP core, WP initializes all and call ob_start(“ob gzhandler”)
  • When my code call ob_end_clean() it fails.

I need a safe way to hide the WP warnings, but I can’t break GZIP enabled configurations ( some plugin I suspect). If is not possible I prefer leave breaking ajax in warning systems and forget the buffer method.

I think a clean way may be:

$buffers = count(ob_get_status(true));
ob_start();
//The wordpress core require
if (count(ob_get_status(true)) == $buffers + 1) {
ob_end_clean();
} else {
ob_flush();
}
//Now the ajax response:
echo '0';

But I’m afraid some of the infinite combinations through PHP versions and configs, WP versions, plugins and configurations breaks somebody. What do you think is a good way to solve this problem?

Related posts

Leave a Reply

1 comment

  1. If you leave any spaces or lines before the open php tag in any files that are required by your plugin (or functions.php) it will break WordPress AJAX.

    BREAKS AJAX:

     <?php
    

    DOESN’T BREAK AJAX:

    <?php