Json Response not utf-8


#1

Good Day… for all and many thanks in advance

i got a simple rest api … but when i try do response with json all utf-8 content are replaced.

The partial code

(...)
if ($v->passes()) {
    $result = $this->db->connection()->select("CALL getPoints();"));
    $data = json_decode(json_encode($result, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK ), true);
} else {
    $data = [
        'msg' => APP_MSG_ERROR_NOT_DATA,
        'error' => true
    ];
}

print_r($data);

return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->withJson($data);

//$response = $this->jsonRender->render($response, 200, $data);
//return $response;

The Result
If i print_r the array $data all the content show as well formated and encoded but when i use jsonRender or withJson it converts to Unicode


#2

Okay, so not sure if this is a Slim issue, or because you are encoding and decoding JSON or not, but for now the following work around works…

(...)
if ($v->passes()) {
    $result = $this->db->connection()->select("CALL getPoints();"));
    $data = json_encode($result, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK );
} else {
    $data = json_encode([
        'msg' => APP_MSG_ERROR_NOT_DATA,
        'error' => true
    ]);
}

then output as normal while only setting the header:

return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->write($data);

in my quick test it returns this:

{"data":"cámera"}

I only had time to test this quickly, so haven’t looked into whether this is an issue with withJson() or not but thought you might want to use the workaround to carry on…


#3

Many thanks and greetings @Crags

i´m using json_decode / json_encode because the query result is an Array with object; and it´s the easy clean way to show it as json

Array ( [0] => stdClass Object ( [id] => 13  .................. ) )

But there is other issue :smiley: i think i miss something …

“error_code”:500,“error_message”:“Could not write to stream”

btw, i´m using slim 3…

and my composer config is

"require": {
    "php": ">=5.5.0",
    "slim/slim": "^3.1",
    "slim/flash": "^0.1.0",
    "monolog/monolog": "^1.17",
    "illuminate/database": "~5.0",
    "zeuxisoo/slim-whoops": "^0.5.0",
    "tuupola/slim-jwt-auth": "^2.0",
    "tuupola/slim-basic-auth": "^2.0",
    "carlosocarvalho/simple-input": "^1.0",
    "alexgarrett/violin": "2.*"
  },

#4

Can you post an example of data - sanitised if you like :slight_smile:


#5

@Crags Sure… Here it is:… and thanks again…

DROP TABLE IF EXISTS `temp_table`;
CREATE TABLE `temp_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titulo` varchar(255) NOT NULL,
  `descripcion` text,
  `categoria` varchar(255) NOT NULL DEFAULT 'Lugar',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `temp_table` (`id`, `titulo`, `descripcion`, `categoria`) VALUES (12, 'Pueblito', '

Small Town

', 'Lugar'); INSERT INTO `temp_table` (`id`, `titulo`, `descripcion`, `categoria`) VALUES (13, 'Cámara', '', 'Cámaras'); INSERT INTO `temp_table` (`id`, `titulo`, `descripcion`, `categoria`) VALUES (14, 'camara', '

Lorem ipsum dolor sit amet

', 'Cámaras'); INSERT INTO `temp_table` (`id`, `titulo`, `descripcion`, `categoria`) VALUES (15, 'cámara 3', '

vitae commodo est finibus

', 'Cámaras');

And the example of function, i´m using SP on database because other internal operations…



$app->get('/points', function (Request $request, Response $response, $args) {
    $category = Input::get('cat');

    $v = new Violin();
    $v->validate([
        'category' => [$category, 'required|min(1)']
    ]);

    if ($v->passes()) {
        $resultados = $this->db->connection()->select("CALL getPoints(:category);", array(':category' => $category));
        // print_r($resultados);  you get the array object
        $data = json_decode(json_encode($resultados, JSON_NUMERIC_CHECK), true);
    } else {
        $data = [
			'msg' => APP_MSG_ERROR_NOT_DATA,
			'error' => true
		];
    }
    print_r($data);

	return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->withJson($data);

	//$response = $this->jsonRender->render($response, 200, $data);
	//return $response;
})->setName('points');



#6

can you just run a var_export($resultados); for me and then I can simply use your data without creating the DB and fetching it - I’ll then run it through and check what the issue is :slight_smile:

thanks


#7

@Crags

sure… excuse me for the delay… but at end is the data:

asking a friend and checking the answers is as you say it is a proper function of JSON Encode however with the flag JSON_UNESCAPED_UNICODE apparently is not enough

thanks.

array (
  0 => 
  stdClass::__set_state(array(
     'id' => '13',
     'titulo' => 'Cámara',
     'descripcion' => '',
     'categoria' => 'Cámaras',
  )),
  1 => 
  stdClass::__set_state(array(
     'id' => '14',
     'titulo' => 'camara',
     'descripcion' => '

Lorem ipsum dolor sit amet

', 'categoria' => 'Cámaras', )), 2 => stdClass::__set_state(array( 'id' => '15', 'titulo' => 'cámara 3', 'descripcion' => '

vitae commodo est finibus

', 'categoria' => 'Cámaras', )), 3 => stdClass::__set_state(array( 'id' => '12', 'titulo' => 'Pueblito', 'descripcion' => '

Small Town

', 'categoria' => 'Lugar', )), )

#8

Okay, thanks for that calo

so the following works fine:

$testData = array (
            0 =>
                array(
                    'id' => '13',
                    'titulo' => 'Cámara',
                    'descripcion' => '',
                    'categoria' => 'Cámaras',
                ),
            1 =>
                array(
                    'id' => '14',
                    'titulo' => 'camara',
                    'descripcion' => '<p>Lorem ipsum dolor sit amet</p>',
                    'categoria' => 'Cámaras',
                ),
            2 =>
                array(
                    'id' => '15',
                    'titulo' => 'cámara  3',
                    'descripcion' => '<p>vitae commodo est finibus</p>',
                    'categoria' => 'Cámaras',
                ),
            3 =>
                array(
                    'id' => '12',
                    'titulo' => 'Pueblito',
                    'descripcion' => '<p>Small Town</p>',
                    'categoria' => 'Lugar',
                ),
        );
        $jsonData = json_encode($testData, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK );

        return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->write($jsonData);

should result in:

[{"id":13,"titulo":"Cámara","descripcion":"","categoria":"Cámaras"},{"id":14,"titulo":"camara","descripcion":"<p>Lorem ipsum dolor sit amet<\/p>","categoria":"Cámaras"},{"id":15,"titulo":"cámara  3","descripcion":"<p>vitae commodo est finibus<\/p>","categoria":"Cámaras"},{"id":12,"titulo":"Pueblito","descripcion":"<p>Small Town<\/p>","categoria":"Lugar"}]

like I said, not sure if this is a Slim issue with the encoding / rendering, but may be worth noting it down or adding it as a bug report for someone to take a look at - reference this post if you need to.

The change above should be enough for you to get it working though :slight_smile:


#9

Many Thanks @Crags

it works like a charm!.. have a nice Day


#10

Hey Calo

Just a quick update now I’ve had chance to have a quick look at it - the reason this was failing originally is that you were not passing through your encoding options to the withJson() function… the below is your original function:

return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->withJson($data);

Where as you should actually be passing it through like this:

return $response->withHeader('Content-Type', 'application/json')->withStatus(200)->withJson($data, null, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);

As you see you can pass through your options to the withJson() function - that works also as expected :slight_smile:


#11

That´s Amazing!..

Thank you very much @Crags for the support, the responses are timely and spot on.


#12

Hy Crags this way it’s work for me! I’m using pt-br language in my project! Thanks! GUY!!! HAIL AND KILL!!!