json_encode indent parameter

  114697
June 2, 2021 22:03 tdegroot96@gmail.com (Timon de Groot)
It's not possible to tell json_encode what indentation level should be 
used when using
the JSON_PRETTY_PRINT option (2, 4, 8, etc). When generating JSON files 
which can be
used/read/edited by users, indentation starts to become a relevant topic.

- JavaScript has a function called JSON.stringify wich accepts the 
optional 'space' parameter
   - See 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify 

- Python has a function called json.dump which accepts the optional 
'indent' parameter
   (which also controls pretty printing)
   - See https://docs.python.org/3/library/json.html#basic-usage

I would like to create an RFC draft to implement an 'indent' parameter.
Before I start a draft, I need to know if this is a good idea, so I 
start with a few questions.

1. What do you think of adding an 'indent' parameter?
2. How would that parameter work when the JSON_PRETTY_PRINT option is 
not passed?
3. What do you think of adding json_encode options instead, like
       JSON_PRETTY_PRINT_INDENT_2 and JSON_PRETTY_PRINT_INDENT_4?

Looking forward to you replies and feedback!

-- 

Kind regards,

Timon de Groot
  114702
June 3, 2021 00:45 davidgebler@gmail.com (David Gebler)
On Wed, 2 Jun 2021, 23:03 Timon de Groot, <tdegroot96@gmail.com> wrote:

> It's not possible to tell json_encode what indentation level should be > used when using > the JSON_PRETTY_PRINT option (2, 4, 8, etc). When generating JSON files > which can be > used/read/edited by users, indentation starts to become a relevant topic. > > - JavaScript has a function called JSON.stringify wich accepts the > optional 'space' parameter > - See > > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify > > - Python has a function called json.dump which accepts the optional > 'indent' parameter > (which also controls pretty printing) > - See https://docs.python.org/3/library/json.html#basic-usage > > I would like to create an RFC draft to implement an 'indent' parameter. > Before I start a draft, I need to know if this is a good idea, so I > start with a few questions. > > 1. What do you think of adding an 'indent' parameter? >
I'm not at all opposed in principle. As you've pointed out, there is both a use case and precedent in other common languages. 2. How would that parameter work when the JSON_PRETTY_PRINT option is
> not passed? >
Give it a default value equivalent to whatever JSON_PRETTY_PRINT spits out at the moment and silently ignore it if not formatting? 3. What do you think of adding json_encode options instead, like
> JSON_PRETTY_PRINT_INDENT_2 and JSON_PRETTY_PRINT_INDENT_4? >
Personally I'd avoid more magic constants. The argument in favour of this approach I suppose would be a) there are in practice a very small number of common values for indentation which tend to be used, 2 and 4 being the most common and b) there is already a third, optional depth parameter which would remain before any fourth spacing parameter. I would say though (a) is true enough but doesn't necessarily cover all use cases, adds more magic constants and doesn't provide equivalence to the JSON libraries of other common languages which permit for custom values, while (b) is less of an issue with PHP 8's named parameters. So if you do go ahead and make an RFC for this, I think my preference would be as a new parameter on json_encode accepting a positive integer.
> Looking forward to you replies and feedback! > > -- > > Kind regards, > > Timon de Groot > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  114703
June 3, 2021 08:00 j.boggiano@seld.be (Jordi Boggiano)
On 03/06/2021 02:45, David Gebler wrote:
> I would say though (a) is true enough but doesn't necessarily cover > all use > cases, adds more magic constants and doesn't provide equivalence to the > JSON libraries of other common languages which permit for custom values, > while (b) is less of an issue with PHP 8's named parameters. > > So if you do go ahead and make an RFC for this, I think my preference would > be as a new parameter on json_encode accepting a positive integer.
I agree, but I'd make it accept a string|int much like JSON.stringify does, because that way you let people pass in tabs too, or "🚀" if that's how you want your JSON indented.. Best, Jordi -- Jordi Boggiano @seldaek - https://seld.be
  114706
June 3, 2021 10:49 tdegroot96@gmail.com (Timon de Groot)
On 3-6-2021 10:00, Jordi Boggiano wrote:
> I agree, but I'd make it accept a string|int much like JSON.stringify > does, because that way you let people pass in tabs too, or "🚀" if > that's how you want your JSON indented..
I like the idea of accepting string|int. Accepting string|int means a zval needs to be used, with the possibility to pass any type of variable (please correct me if I'm wrong here). Should the function throw an error when it receives anything other than a string|int? -- Kind regards, Timon de Groot
  114711
June 3, 2021 14:15 george.banyard@gmail.com ("G. P. B.")
On Thu, 3 Jun 2021 at 11:49, Timon de Groot <tdegroot96@gmail.com> wrote:

> On 3-6-2021 10:00, Jordi Boggiano wrote: > > I agree, but I'd make it accept a string|int much like JSON.stringify > > does, because that way you let people pass in tabs too, or "🚀" if > > that's how you want your JSON indented.. > > I like the idea of accepting string|int. > > Accepting string|int means a zval needs to be used, with the possibility > to pass any type of variable (please correct me if I'm wrong here). > Should the function throw an error when it receives anything other than > a string|int? >
That's incorrect, as of PHP 8.0 Fast ZPP has a way to deal with the most common union types, including int|string. Best regards, George P. Banyard
  114714
June 3, 2021 15:48 tdegroot96@gmail.com (Timon de Groot)
On 3-6-2021 16:15, G. P. B. wrote:
> That's incorrect, as of PHP 8.0 Fast ZPP has a way to deal with the most > common union types, including int|string. > > Best regards, > > George P. Banyard
I found that STR_OR_LONG works fine, thanks for acknowledging! -- Kind regards, Timon de Groot
  114715
June 3, 2021 15:53 ayesh@php.watch (Ayesh Karunaratne)
Hi Timon,
Thank you for this RFC. I think the `string|int $indent` approach is great 🚀!

Reading the PR, it looks like `$indent=0` is essentially turning off
pretty-print, which I think is intuitive.

Do you plan to add any sort of validation on negative integers?
Perhaps throw a `\ValueError` exception on $indent < 0?

---
Thank you.
Ayesh.

On Thu, Jun 3, 2021 at 9:19 PM Timon de Groot <tdegroot96@gmail.com> wrote:
> > On 3-6-2021 16:15, G. P. B. wrote: > > That's incorrect, as of PHP 8.0 Fast ZPP has a way to deal with the most > > common union types, including int|string. > > > > Best regards, > > > > George P. Banyard > > I found that STR_OR_LONG works fine, thanks for acknowledging! > > -- > > Kind regards, > > Timon de Groot > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >
  114716
June 3, 2021 16:03 tdegroot96@gmail.com (Timon de Groot)
On 3-6-2021 17:53, Ayesh Karunaratne wrote:
> Hi Timon, > Thank you for this RFC. I think the `string|int $indent` approach is great 🚀! > > Reading the PR, it looks like `$indent=0` is essentially turning off > pretty-print, which I think is intuitive. Basically, yes. With `$indent=0`, no indentation will take place but new
lines will still be added.
> Do you plan to add any sort of validation on negative integers? > Perhaps throw a `\ValueError` exception on $indent < 0?
Good question. Personally I'd prefer clamping $indent to 0 when it reaches below 0. But I'd like to hear about what other particpants think about such behavior. Thank you for your feedback :). -- Kind regards, Timon de Groot
  114725
June 4, 2021 06:24 j.boggiano@seld.be (Jordi Boggiano)
On 03/06/2021 18:03, Timon de Groot wrote:
> On 3-6-2021 17:53, Ayesh Karunaratne wrote: >> Hi Timon, >> Thank you for this RFC. I think the `string|int $indent` approach is >> great 🚀! >> >> Reading the PR, it looks like `$indent=0` is essentially turning off >> pretty-print, which I think is intuitive. > Basically, yes. With `$indent=0`, no indentation will take place but > new lines will still be added. >> Do you plan to add any sort of validation on negative integers? >> Perhaps throw a `\ValueError` exception on $indent < 0? > > Good question. Personally I'd prefer clamping $indent to 0 when it > reaches below 0. But I'd like > to hear about what other particpants think about such behavior. > IMO the JS spec is quite reasonable there, and I would say copying it
1:1 would be fine:     If this is a Number, it indicates the number of space characters to use as white space; this number is capped at 10 (if it is greater, the value is just 10). Values less than 1 indicate that no space should be used.     If this is a String, the string (or the first 10 characters of the string, if it's longer than that) is used as white space. If this parameter is not provided (or is null), no white space is used. Best, Jordi -- Jordi Boggiano @seldaek - https://seld.be
  114705
June 3, 2021 10:48 tdegroot96@gmail.com (Timon de Groot)
> So if you do go ahead and make an RFC for this, I think my preference > would be as a new parameter on json_encode accepting a positive integer.
Thank your for your input, I'll start working on an RFC to introduce a new parameter for json_encode.
  114708
June 3, 2021 11:35 guilliam.xavier@gmail.com (Guilliam Xavier)
Hello,

I have seen a similar discussion for var_export(), and the answer was
basically "use a regex". E.g.:

    $json = preg_replace_callback(
        '/^(?: {4})+/m',
        fn ($m) => str_repeat($indent, strlen($m[0]) / 4),
        json_encode($data, JSON_PRETTY_PRINT)
    );

That said, I wouldn't mind a new indent parameter (but note that allowing
an arbitrary string [not limited to whitespace] might result in invalid
JSON).

Regards,

-- 
Guilliam Xavier