0

I'm using Slim php framework with a database that contains complex HTML content, but when calling the get method it returns a bad json. Here's the return code

$response->withJson($resp, 201); 

I also tried with json_encode but still not valid:

$response->withJson(json_encode($resp), 201);

I just noticed that the JSON returned is missing '}]' at the end, is it possible that the content is too long to be transferred as a string ? Also when i call var_dump($resp) it shows my content correctly

aaa
  • 57
  • 4
  • 11
  • because it's attempting to encode html into strings, the `"` characters in the html are probably causing the issue, try including the option `JSON_HEX_QUOT` as the $encodingOptions parameter in `$response->withJson();` ie something like `$response->withJson($resp,201,JSON_HEX_QUOT);` – shamsup Apr 25 '16 at 15:27
  • Out of curiosity... What does "returns a bad json" mean exactly? – Álvaro González Apr 25 '16 at 15:28
  • Can we get an example of the contents in `$resp`? – shamsup Apr 25 '16 at 15:36
  • I just noticed that the JSON returned is missing '}]' at the end, is it possible that the content is too long to be transferred as a string ? – aaa Apr 25 '16 at 15:48
  • You are probably echoing two characters, most likely spaces somewhere before the route or after $app->run() – Mika Tuupola Apr 25 '16 at 15:59
  • @aaa, let's make sure that your problem is reproducible. Since you have a problem, I am sure you have a raw data with which the problem can be reproduced. Please, share that with us. Then show what is the JSON generated from there. Then please, tell us, what did the browser receive, by checking the network tab. Then please, describe how is the problem detected? Do you get an invalid HTML at the end? If so, is your JSON supposed to be an attribute value enclosed into apostrophe and/or quote. You specified that var_dump returns something you expected. Are you sure the problem occurs at the conv? – Lajos Arpad Apr 25 '16 at 15:59
  • @LajosArpad The raw data is too long to be shared here, the json returned is missing a '}]' at the end. JSONLint error: 'Expecting '}', ',', got 'EOF'' But when i limit the result to a small number of posts it returns a valid JSON – aaa Apr 25 '16 at 16:07
  • @aaa, I see. Length might be a problem, or it might be a coincidence that your JSON problem happens to occur for the longer string. For now, let us now assume either case. Please, show me how you use the JSON on client-side, where do you echo it out? Or is it a response to an AJAX request? – Lajos Arpad Apr 25 '16 at 16:10
  • @LajosArpad I use angular js http request, the weird thing is that when i use the same api call on a different table (a one without large content) it works just fine – aaa Apr 25 '16 at 16:22
  • Why are you attempting to return HTML as JSON? literally makes no sense. – geggleto Apr 25 '16 at 18:26
  • @geggleto I have a mobile app that read blog posts (originally posted from a website) and render them with HTML – aaa Apr 25 '16 at 18:29
  • ok... so you can pull from Slim using a GET route and use php-view or twig-view to render your HTML. – geggleto Apr 25 '16 at 18:32
  • Just today I've been JSON-encoding like 22 MB worth of data with 32-bit PHP/5.5.x—and I'm reusing an previous codebase that's been used in Production for datasets over 500 MB. I don't know how much data you're transmitting but I don't think that large size can lead to truncation. You should determine where exactly in your flow that truncation is happening. – Álvaro González Apr 25 '16 at 18:48

5 Answers5

1

If you are missing }] at then end, then one of your PHP files has two spaces (or new lines) before the opening <?php.

Another solution is to replace your $app->run() with:

$response = $app->run(true); //Silent mode, wont send the response
$response = $response->withoutHeader("Content-Length"); //Remove the Content-Length
$app->respond($response); //Now we send the response

Hopefully, we'll have a proper fix in the next version!

Rob Allen
  • 12,643
  • 1
  • 40
  • 49
0

Maybe a problem with the characters codification. Have you tried this?

json_encode($array, JSON_UNESCAPED_UNICODE)

Any way to return PHP `json_encode` with encode UTF-8 and not Unicode?

Community
  • 1
  • 1
SvOzMaS
  • 1
  • 2
0

As far as I can tell, Slim does not care doing error checking:

/**
 * Json.
 *
 * Note: This method is not part of the PSR-7 standard.
 *
 * This method prepares the response object to return an HTTP Json
 * response to the client.
 *
 * @param  mixed  $data   The data
 * @param  int    $status The HTTP status code.
 * @param  int    $encodingOptions Json encoding options
 * @return self
 */
public function withJson($data, $status = 200, $encodingOptions = 0)
{
    $body = $this->getBody();
    $body->rewind();
    $body->write(json_encode($data, $encodingOptions));

    return $this->withStatus($status)->withHeader('Content-Type', 'application/json;charset=utf-8');
}

... so you'll need to do it yourself. The bare minimum is a call to json_last_error().

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
0

Because it's attempting to encode html into strings in JSON, the " characters in the html are probably causing the issue. Try including the option JSON_HEX_QUOT as the 3rd parameter.

$response->withJson($resp,201,JSON_HEX_QUOT);

This will escape the " character in the html to the unicode literal \u0022, preventing clashes.

shamsup
  • 1,952
  • 14
  • 18
  • If you browse Slim source code you'll see it doesn't have its own JSON encoder; `withJson()` is little more than a call to native `json_encode()` which —I can tell you from the experience— works properly, esp. with something as simple as a double quote. – Álvaro González Apr 25 '16 at 15:33
  • I just tried your solution but still the same problem. – aaa Apr 25 '16 at 15:35
  • it's possible that there's something else causing his issue, but without an example of what he's converting, it's difficult to tell. I've used this to solve escaping issues in JSON before, specifically with double quotes and backslashes. – shamsup Apr 25 '16 at 15:35
0

What you likely want.

  1. Rendering HTML is possible by using slim/php-view or slim/twig-view
  2. Use AJAX to pull the HTML and place it in your mobile app.

Using JSON is silly since you still have to server side render the HTML, then package it up into a JSON format. Doing this is generally a bad idea since JSON in the spec will only accept UTF-8 and there's no way around that.

geggleto
  • 2,605
  • 1
  • 15
  • 18
  • He might need to include metadata or do something as simple as retrieving several items at the same time (plain HTML response would imply one HTTP connection per item). Having a clean JSON API is not necessarily nonsense. But apart from that, I think this should have been posted as comment rather than answer. When you have a problem with your code you just fix it, not dump the entire design. – Álvaro González Apr 25 '16 at 18:53