1

In my PHP file I have this code (not the real code, just for demonstration purposes):

ob_start();
var_export(headers_sent());
var_export(ob_get_status());
header('Content-Type: text/html');
header('Content-Type: application/json');

But the response headers end up being text/html instead of application/json. From my understanding the last call to header() should be what is used - espacially since headers_sent() returns false and ob_get_status() will also confirm that output buffering is on.

In PHP documentation for header() it says this statement though in the changelog for version 5.1.2:

This function now prevents more than one header to be sent at once as a protection against header injection attacks.

I'm not quite sure what that means though - because this certainly hasn't been an issue all the time since PHP 5.1.2.

And even WordPress is relying on calling header() multiple times, eg. in wp-admin/admin-ajax.php where it in the very beginning of the file calls @header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); and then later when it has determined that the action needs to return JSON data it calls @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) ); in wp_send_json() in wp-includes/functions.php.

Is there a change I can do on the server to make PHP use the last given content type? I obviously cannot change Wordpress core files.

I use Debian 9.3, PHP 7.1.3, Apache 2.4.25.

Site note: The effect of this problem is that the Media Library doesn't load any images in grid mode and activity indicator just keeps spinning.

!! UPDATE !!

Now I found out that this happens because I have the following in my .htaccess file:

php_value output_handler mb_output_handler

I have forgotten why I have that in there, so I'm not sure I dare remove it... But why does it have that effect?

6
  • Keep reading. "The optional replace parameter indicates whether the header should replace a previous similar header, or add a second header of the same type. By default it will replace, but if you pass in FALSE as the second argument you can force multiple headers of the same type." Feb 27 '18 at 20:03
  • Right, forgot to mention I read that too. But why then doesn't it work like that?! According to the code it should replace it... Feb 28 '18 at 9:58
  • mb_output_handler? You were doing character set conversion? This really shouldn't be necessary with WordPress; it tries very hard to have everything in UTF-8. Feb 28 '18 at 16:03
  • @MichaelHampton You're probably right, but the site runs a lot other stuff than Wordpress as well... Feb 28 '18 at 22:14
  • Use a different php-fpm pool, then? Feb 28 '18 at 22:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.