-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[RFC] Add json_encode indent parameter #7093
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
Conversation
ext/json/json.stub.php
Outdated
@@ -2,7 +2,7 @@ | |||
|
|||
/** @generate-class-entries */ | |||
|
|||
function json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false {} | |||
function json_encode(mixed $value, int $flags = 0, int $depth = 512, string|int $indent = 4): string|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 think accepting string only here is enough, passing ' '
is easy as passing 4
but simple type is enough.
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.
It does make it more difficult to see that $indent=' '
specifies 4 spaces and that this indentation is actually consistent with some other call site that uses $indent=4
.
Also, I prefer parameters having pure types rather than composite. Since we have named parameters now it might make sense to split into two parameters:
json_encode($value, indent: 4, indent_char: ' ');
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 agree with @dtakken about pure types rather than composite. As I was scanning the code I kept trying to figure out why the string|int
types were being used instead of only int
. Realizing finally if a string
is passed as the argument the string
literally is the indent value.
However, spiting this into two parameters does remove or complicate the feature of multiple characters:
json_encode($value, indent: 4, indent_chars: '🚀🌙🌠🌎');
// What to do if indent = 2 and indent_chars has more than 2 chars?
json_encode($value, indent: 2, indent_chars: '🚀🌙🌠'); // error? ignore the 3rd char?
// What to do if indent = 3 and indent_chars has less than 3 chars?
json_encode($value, indent: 3, indent_chars: '🚀🌙'); // repeat '🚀🌙🚀'? error? something else?
ext/json/json.c
Outdated
bool default_indent_used = 0; | ||
|
||
if (indent_str == 0) { | ||
indent_str = zend_string_init(" ", strlen(" "), 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.
Would it be better to base the indent_str
off of the stack instead of heap?
ext/json/json_encoder.c
Outdated
|
||
if (options & PHP_JSON_PRETTY_PRINT) { | ||
if (encoder->indent_str) { | ||
indent_length = ZSTR_LEN(encoder->indent_str); |
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.
Why does this care about indent_length? Can't we just append indent_str unconditionally? I don't think we need to optimize for the indent=0 case.
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.
Because indent_length = 0 is basically a noop for the indent function. I have updated the function to be more clear about that scenario.
Let me know if you still think it'd be better to not care about the indent_length
!
Co-authored-by: Nikita Popov <[email protected]>
Co-authored-by: Nikita Popov <[email protected]>
Co-authored-by: Nikita Popov <[email protected]>
Just wondering, are there any cases today where I could very well be wrong about the current state of var_dump(
json_decode(json_encode($someData));
); However after this change doing the same thing, but with this example: var_dump(
json_decode(json_encode(['unicode' => "supported"], JSON_PRETTY_PRINT, 512, '🚀🚀'));
); You get the error in the decode, but not the encode. This example may not seem practical - however other JSON decode functions will also be expected to fail as well. Yet your app is none the wiser producing invalid JSON for you APIs. Wouldn't it be better (i.e more clear) if the error occurred closer to the source of the issue? Instead it could throw an exception when
|
Co-authored-by: Tyson Andre <[email protected]>
@tdgroot There has been no change here for a while. Are you still planning on pursuing this RFC? |
@iluuu1994 yes I intent to finish this PR, had quite a busy year after I dived into this. |
Removed the possibility to enter a string as indentation, as it raises more questions than answers. So for now, it's only possible to change the indentation by passing a number to the `indent` parameter. Perhaps in the future, we could introduce a fifth parameter like `indent_char`, with which a character can be passed to specify which character needs to be used for the indentation.
Co-authored-by: Jakub Zelenka <[email protected]>
Co-authored-by: Michael Voříšek <[email protected]>
Instead of future |
@tdgroot It might make sense you start voting on the RFC so we can get it to 8.2... |
Hi, Tim here from issue #8864. I just wanted to say don't forget Tabs. 🙂 I would add two new pretty print variation flags: Tabs would shrink indentation size to 1 bytes instead of 4 bytes which could have a significant impact on an entire serialized JSON object. Tabs are suited for both byte optimization and readability. |
RFC has been declined |
+ for having customizable indent string or at least |
+1 because of lack of compatibility with current MySQL JSON format |
RFC: https://wiki.php.net/rfc/json_encode_indentation