php - JSON output is empty but only in the browser
one text
This might be one of the weirdest problems I've run into and I can't figure it out...
I have a WordPress plugin that acts as an API endpoint for a mobile app. This customer's site has one article that is breaking the JSON encoded output. When I call the API via CURL I get an empty result and when I call the API via a web browser I get a white screen. But if I output the JSON encoded data to a file, it works.
Here are all the details that I can think of...
1) Server is NGINX w/ PHP 7.0 (yeah, I know, it needs to be updated). 2) I get no errors in the NGINX or PHP logs and json_last_error returns no errors.
3a) Problem Call: https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345 3b) Actual Output: https://landline.media/json-notworking.txt
4a) Example Working Call: https://landline.media/?unipress-api=get-article&article-id=23109&device-id=12345 4b) Actual Output: https://landline.media/json-working.txt
I setup a couple of alternative outputs with the API call, for testing...
print_r output (not json_encoded): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&printr=true
When I unset the Object->formatted_post_content, the json_encoded call works: https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&unset=true
When I just output the Object->formatted_post_content, the json_encoded call fails: https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&formatted_post_content=true
When I just output a substring of the json_encoded Object->formatted_post_content, the json_encoded call works (but only for a certain range of substrings and they even overlap, which is extra weird)...
substr( 0, 9892 ): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&str1=true
substr( 9011, 8993 ): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&str2=true
substr( 17042, 10047 ): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&str3=true
substr( 21806, 9217 ): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&str4=true
That's where I stopped checking ranges, because the strlen is 134,037 and I don't have a time to figure them all out :-D..
Okay, so even extra weird, if I use any of those substr to replace the original formatted_post_content and json encode the entire object, it still fails... but I can use a smaller substr() and it works... I only found the first one... substr( 0, 3175 ): https://landline.media/?unipress-api=get-article&article-id=19131&device-id=12345&substr=true
I also tried...
removing all invisible characters from formatted_post_content preg_replace( '/[\x00-\x1F\x7F\xA0]/u', '', Object->formatted_post_content );
.
outputting the file contents of json-notworking.txt.
...neither of which helped.
FWIW, this is the code I've been testing with...
function api_response( $response ) {
header( 'HTTP/1.1 ' . $response['http_code'] . ' ' . $this->http_code_string( $response['http_code'] ) );
header( 'Content-type: application/json' );
if ( ! empty( $_GET['printr'] ) ) {
print_r( $response['body'] );
} else if ( !empty( $_GET['unset'] ) ) {
unset( $response['body']->formatted_post_content );
echo json_encode( $response['body'] );
} else if ( !empty( $_GET['formatted_post_content'] ) ) {
echo json_encode( $response['body']->formatted_post_content );
} else if ( !empty( $_GET['str1'] ) ) {
$response['body']->formatted_post_content = substr( $response['body']->formatted_post_content, 0, 9892 );
echo json_encode( $response['body']->formatted_post_content );
} else if ( !empty( $_GET['str2'] ) ) {
$response['body']->formatted_post_content = substr( $response['body']->formatted_post_content, 9011, 8993 );
echo json_encode( $response['body']->formatted_post_content );
} else if ( !empty( $_GET['str3'] ) ) {
$response['body']->formatted_post_content = substr( $response['body']->formatted_post_content, 17042, 10047 );
echo json_encode( $response['body']->formatted_post_content );
} else if ( !empty( $_GET['str4'] ) ) {
$response['body']->formatted_post_content = substr( $response['body']->formatted_post_content, 21806, 9217 );
echo json_encode( $response['body']->formatted_post_content );
} else if ( ! empty( $_GET['substr'] ) ) {
$response['body']->formatted_post_content = substr( $response['body']->formatted_post_content, 0, 3175 );
echo json_encode( $response['body'] );
} else {
echo json_encode( $response['body'] );
}
exit;
}
If anyone has any ideas, I'd greatly appreciate them. Thanks!
Source