Thomas B.
Thomas B.

Reputation: 2296

PHP Warning demolishes JSON response

I'm implementing an ajax fileupload for my php application (using CodeIgniter).

I detect if the uploaded POST data is to large (>post_max_size) according to http://andrewcurioso.com/2010/06/detecting-file-size-overflow-in-php/ and try to send an appropriate JSON-encoded error response.

But the corresponding php warning included in the output completely destroys my JSON response !

<br />
<b>Warning</b>:  POST Content-Length of 105906405 bytes exceeds the limit of 8388608 bytes in <b>Unknown</b> on line <b>0</b><br />
[{"error":"Posted data is too large. 105906405 bytes exceeds the maximum size of 8388608 bytes."}]

I don't want to parse and filter the warning out on client side, that seems ugly. And disabling all php warnings globally seems inappropriate.

Can I disable specific PHP warnings in the context of a php function? Or wrap it inside of a valid json response?

Upvotes: 17

Views: 7414

Answers (4)

Enrico Sandoli
Enrico Sandoli

Reputation: 41

I have just had the same problem implementing an upload script which requires communication back to the calling script. Some php warnings were corrupting the output response.

I have resorted to the php output buffering functions. This is how I got rid of the warning output messages:

ob_start(); // start output buffering (we are at the beginning of the script)

[ ... ] // the script actual functionality is unchanged

ob_end_clean(); // this clears any potential unwanted output

exit($my_json_encoded_response); // and this just outputs my intended response

This solved my problem.

Upvotes: 4

xception
xception

Reputation: 4297

On production server: Always disable php warnings.

On development machine: Disable all warnings for that page for the purpose of testing and re-enable after testing is complete and functionality confirmed as working.

Hint: I prefer to have a variable globally set and depending on that enable or disable all php and database warning notifications. You could set that in .htaccess for example if you use apache. I have this in .htaccess:

  • production: SetEnv DEVELOPMENT Off
  • development: SetEnv DEVELOPMENT On

And in the php code:

if( strtolower(getenv('DEVELOPMENT')) == "on" ) {
        ini_set("display_errors",2);
        ini_set('error_reporting', E_ALL | E_STRICT);
}

To disable all errors from .htaccess use

php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
php_value docref_root 0
php_value docref_ext 0

If you want to get really tricky you could add a check like:

if(error_get_last() !== null)

and set a http header and check that from javascript both for json output and when loading your page and take a look at the error log or display the error on screen if you prefer that, still I strongly recommend that you disable the error showing code in the production environment.

For more in-depth talk about this take a look at this article.

Upvotes: 16

Bart Friederichs
Bart Friederichs

Reputation: 33533

You can set a user-defined error handler: http://www.php.net/manual/en/function.set-error-handler.php

You can also use the output buffering functions to wrap it. ob_start, ob_end_flush and others.

However, it is always best to have PHP error_reporting set to false in production systems, then catch errors and wrap them in your JSON.

Upvotes: 2

Wern Ancheta
Wern Ancheta

Reputation: 23317

Or you can just change the post max size on php.ini file:

post_max_size = 10M //change this line to whatever fits your needs

But depending on what the users should be uploading, you should also try checking the file size of the files that they're uploading.

Upvotes: 0

Related Questions