-
Notifications
You must be signed in to change notification settings - Fork 11.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[12.x] Add json:unicode cast to support JSON_UNESCAPED_UNICODE encoding #54992
base: 12.x
Are you sure you want to change the base?
Conversation
* @return string | ||
*/ | ||
protected function asJson($value) | ||
protected function asJson($value, $isUnicode = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like idea of adding a single-use parameter to asJson
. What if we wanted to add (for whatever reason), the ability to do JSON_PRETTY_PRINT
? Or maybe JSON_PARTIAL_OUTPUT_ON_ERROR
?
I think it should be asJson($value, int $flags = 0)
and we can add an additional method to process the flags.
Maybe something like this?
protected function getJsonCastFlags($key): int
{
$flags = 0;
if ($this->hasCast($key, ['json:unicode'])) {
$flags |= JSON_UNESCAPED_UNICODE;
}
return $flags;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your review!
I've addressed your feedback in commit 61fad07.
Please let me know if there's anything else that needs adjustment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could probably even add a type-check to ./types/Database/Eloquent/Casts
to ensure that only a valid integer is returned 🤔
* @param int $flags | ||
* @return string | ||
*/ | ||
protected function asJson($value) | ||
protected function asJson($value, $flags = 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could possibly make this type more precise:
* @param int $flags | |
* @return string | |
*/ | |
protected function asJson($value) | |
protected function asJson($value, $flags = 0) | |
* @param int-mask-of<JSON_*> $flags | |
* @return string | |
*/ | |
protected function asJson($value, $flags = 0) |
* Get JSON casting flags for the specified attribute. | ||
* | ||
* @param string $key | ||
* @return int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Therefore, you can narrow the return here as well:
* @return int | |
* @return int-mask-of<JSON_*> |
Description
This PR introduces a new
json:unicode
cast type for Eloquent attributes, allowing JSON encoding withJSON_UNESCAPED_UNICODE
. This makes it easier to store and retrieve JSON data without Unicode escaping (\uXXXX
), which is particularly useful for applications that handle non-ASCII characters like Japanese, Chinese, or emojis.Why?
Currently, Eloquent's
json
cast escapes Unicode characters by default, making JSON-encoded attributes harder to read for humans and increasing the need for manual decoding. Developers often work around this by overriding accessors/mutators or manually usingjson_encode($value, JSON_UNESCAPED_UNICODE)
, which is cumbersome.By introducing
json:unicode
, developers can simply specify it in the$casts
array:This automatically applies
JSON_UNESCAPED_UNICODE
when encoding the attribute.Changes
Core Modifications
Illuminate\Database\Eloquent\Casts\Json
:$flags
parameter toJson::encode()
, allowing different encoding options.Illuminate\Database\Eloquent\Concerns\HasAttributes
:json:unicode
to the list of castable types.asJson()
to check ifjson:unicode
is used and applyJSON_UNESCAPED_UNICODE
.Tests
testJsonCastingRespectsUnicodeOption()
json:unicode
encodes JSON without escaping Unicode characters.testModelJsonUnicodeCastingFailsOnUnencodableData()
JsonEncodingException
is thrown whenjson:unicode
encounters malformed UTF-8 characters.Before & After Example
Before (using default json cast)
After (using json:unicode cast)
Backward Compatibility
json
cast remains unchanged, ensuring full backward compatibility.json:unicode
when needed.Potential Edge Cases Considered
json:unicode
still throwsJsonEncodingException
when encoding fails.null
values are properly handled.json
andjson:unicode
return arrays when accessed.