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