Is it possible to use cyrillic symbols in Lumen(by Laravel)?
Asked Answered
S

1

7

The issue is I can't use any russian symbols in the response()->json() method. I've already tried the following code:

return response()->json(['users' => 'тест']);

and

return response()->json(['users' => mb_convert_encoding('тест', 'UTF-8')]);

and

return response()->json(
       ['users' => mb_convert_encoding('тест', 'UTF-8')])
       ->header('Content-Type', 'application/json; charset=utf-8');

I've checked the default encoding:

mb_detect_encoding('тест'); // returns 'UTF-8'

Also, all my files have been converter to UTF-8 without BOM. I've added the default character set to the .htaccess file(AddDefaultCharset utf-8) as well.

But, I still get the wrong response like here:

{"users":"\u0442\u0435\u0441\u0442"}
Spellbinder answered 1/12, 2015 at 20:5 Comment(5)
Why do you think it's wrong response?Palaeo
I mean it's wrong for me)). I expect {'users': 'тест'}Spellbinder
u0442 is a unicode representation of тPalaeo
Cool! But, I hope I don't convert all unicode symbols to russian manually. I want to use something like this json_encode(['users', 'тест'], JSON_UNESCAPED_UNICODE)Spellbinder
Probably, it isn't completely correct, but this code return response()->make(json_encode(['users' => 'тест'], JSON_UNESCAPED_UNICODE))->header('Content-Type', 'application/json; charset=utf-8'); has solved my issue.Spellbinder
W
10

The response that you are getting:

 {"users":"\u0442\u0435\u0441\u0442"}

is valid JSON!

That being said, if you don't want to encode the UTF-8 characters, you can simply just do this:

 $data = [ 'users' => 'тест' ];
 $headers = [ 'Content-Type' => 'application/json; charset=utf-8' ];

 return response()->json($data, 200, $headers, JSON_UNESCAPED_UNICODE);

The output would then be

 {"users":"тест"}

Why does this work?

Calling the response() helper will create an instance of Illuminate\Routing\ResponseFactory. ResponseFactory's json function has the following signature:

public function json($data = [], $status = 200, array $headers = [], $options = 0)

Calling json() will create a new instance of Illuminate\Http\JsonResponse, which will be the class responsible for running json_encode for your data. Inside the setData function in JsonResponse, your array will be encoded with the $options provided on the response()->json(...) call:

 json_encode($data, $this->jsonOptions);

As you can see on the documentation on php.net for the json_encode function and the documentation on php.net for the json_encode Predefined Constants, JSON_UNESCAPED_UNICODE will encode multibyte Unicode characters literally (default is to escape as \uXXXX).

It is important to note that JSON_UNESCAPED_UNICODE has only been supported since PHP 5.4.0, so make sure you are running 5.4.0 or newer to use this.

Wizardry answered 10/12, 2015 at 22:40 Comment(3)
Lumen does not work with php < 5.4, it probably required the 5.5.9 from the start (although the composer constraint was added only recently)Brier
Thank you for the clarification @timgws! It's the really nice answer!Spellbinder
@Brier you are correct that lumen does not work with PHP >= 5.5.9, but the note for PHP < 5.4.0 is related to json_encode, and not directly for the Laravel framework.Wizardry

© 2022 - 2024 — McMap. All rights reserved.