# [Discussion] Why can't I do "{$a::class}"?

- Thread: https://externals.io/message/123362
- Original archive: https://news-web.php.net/php.internals/123362
- Started by Peter Stalman on 2024-05-19T08:30:08+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #123362 — Peter Stalman — 2024-05-19T08:30:08+00:00

URL: https://externals.io/message/123362#123362

Hi Internals,

Obviously we can't use constants or functions directly in strings using
variable parsing, I assume because it lacks the easily detectable $.

However, we _can_ use methods because the object variable has the $, which
I assume is the reason methods work and functions don't.

I feel like it's something that _could_ have been added when dynamic access
of static members support was added in 5.3.0, but maybe it was overlooked
or decided against?  Consider:

```
<?php

$a = new A();

echo " {A::$static_property} \n"; // doesn't work (unless $static_property
is a variable)
echo " {$a::$static_property} \n"; // works

echo " {A::static_method()} \n"; // doesn't work (just text)
echo " {$a::static_method()} \n"; // works

echo " {A::constant} \n"; // doesn't work
echo " {$a::constant} \n"; // doesn't work either, but why?

?>
```


Also, as a side note, why does this hack below work?  It seems like
something that would use `eval()`, but doesn't.  Take a look:

https://3v4l.org/aPCSD

I found it at the bottom of the manual entry for Strings[1].  Not something
I would use, but it's interesting to see.

Thanks,
Peter

[1]: https://www.php.net/manual/en/language.types.string.php#91628

---

## #123365 — Robert Landers — 2024-05-19T10:39:29+00:00

URL: https://externals.io/message/123362#123365 · In reply to: #123362

>
> Hi Internals,
>
> Obviously we can't use constants or functions directly in strings using variable parsing, I assume because it lacks the easily detectable $.
>
> However, we _can_ use methods because the object variable has the $, which I assume is the reason methods work and functions don't.
>
> I feel like it's something that _could_ have been added when dynamic access of static members support was added in 5.3.0, but maybe it was overlooked or decided against?  Consider:
>
> ```
> <?php
>
> $a = new A();
>
> echo " {A::$static_property} \n"; // doesn't work (unless $static_property is a variable)
> echo " {$a::$static_property} \n"; // works
>
> echo " {A::static_method()} \n"; // doesn't work (just text)
> echo " {$a::static_method()} \n"; // works
>
> echo " {A::constant} \n"; // doesn't work
> echo " {$a::constant} \n"; // doesn't work either, but why?
>
> ?>
> ```
>
>
> Also, as a side note, why does this hack below work?  It seems like something that would use `eval()`, but doesn't.  Take a look:
>
> https://3v4l.org/aPCSD
>
> I found it at the bottom of the manual entry for Strings[1].  Not something I would use, but it's interesting to see.
>
> Thanks,
> Peter
>
> [1]: https://www.php.net/manual/en/language.types.string.php#91628

In general, it would be nice to have some proper inline string
templating, like other languages (js, C#, etc). At least some way to
evaluate an expression and format. I'm thinking like in C#:

$"Price: {price:C2}, Quantity: {quantity}, Discount: {discount:P1},
Total after discount: {(price * quantity * (1 - discount)):N2}"

Price is formatted using currency with 2 decimal places, discount is
formatted using percentage and one decimal, and N is a number format
with 2 decimals.

Robert Landers
Software Engineer
Utrecht NL

---

## #123366 — Ilija Tovilo — 2024-05-19T11:15:12+00:00

URL: https://externals.io/message/123362#123366 · In reply to: #123362

Hi Peter


>
> echo " {A::$static_property} \n"; // doesn't work (unless $static_property is a variable)
> echo " {$a::$static_property} \n"; // works
>
> echo " {A::static_method()} \n"; // doesn't work (just text)
> echo " {$a::static_method()} \n"; // works
>
> echo " {A::constant} \n"; // doesn't work
> echo " {$a::constant} \n"; // doesn't work either, but why?

It would be straightforward to allow all expressions that start with a
`$` in string interpolation, as I've noticed a couple of years ago
[1]. This restriction seems rather arbitrary.

I think I held off proposing this because I was planning on proposing
a more complete form of string interpolation [2]. However, the
backwards-compatible syntax was largely disliked, so I withdrew the
RFC.

I wasn't particularly fond of introducing more forms of strings (e.g.
$"", f"", etc.) to avoid the BC break, because there are already
plentiful:

* ''
* ""
* `` (yes, these allow interpolation)
* <<<HD ... HD
* <<<'HD' ... HD

Adding at least the two expected ones ($"" and $<<<HD ... HD) would
bump that up to 7 forms.

There were also suggestions to extend strings in a more generic way,
akin to JavaScripts template strings [3], but I didn't have any use
for this myself.

Ilija

[1] https://github.com/php/php-src/compare/master...iluuu1994:php-src:lift-variable-restriction-for-brace-dollar-string-interpolation

[2] https://wiki.php.net/rfc/arbitrary_string_interpolation

[3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

---

## #123367 — Ilija Tovilo — 2024-05-19T11:22:52+00:00

URL: https://externals.io/message/123362#123367 · In reply to: #123366

>
> Hi Peter
>
> 
> > […]
>
> There were also suggestions to extend strings in a more generic way,
> akin to JavaScripts template strings [3], but I didn't have any use
> for this myself.
>
> [3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

What I actually wanted to reference were "tagged templates":

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates

Sorry for the confusion.

Ilija

---

## #123461 — Valentin Udaltsov — 2024-05-29T20:43:40+00:00

URL: https://externals.io/message/123362#123461 · In reply to: #123362

> Hi Internals,
>
> Obviously we can't use constants or functions directly in strings using
> variable parsing, I assume because it lacks the easily detectable $.
>
> However, we _can_ use methods because the object variable has the $, which
> I assume is the reason methods work and functions don't.
>
> I feel like it's something that _could_ have been added when dynamic
> access of static members support was added in 5.3.0, but maybe it was
> overlooked or decided against?  Consider:
>
> ```
> <?php
>
> $a = new A();
>
> echo " {A::$static_property} \n"; // doesn't work (unless $static_property
> is a variable)
> echo " {$a::$static_property} \n"; // works
>
> echo " {A::static_method()} \n"; // doesn't work (just text)
> echo " {$a::static_method()} \n"; // works
>
> echo " {A::constant} \n"; // doesn't work
> echo " {$a::constant} \n"; // doesn't work either, but why?
>
> ?>
> ```
>
>
> Also, as a side note, why does this hack below work?  It seems like
> something that would use `eval()`, but doesn't.  Take a look:
>
> https://3v4l.org/aPCSD
>
> I found it at the bottom of the manual entry for Strings[1].  Not
> something I would use, but it's interesting to see.
>
> Thanks,
> Peter
>
> [1]: https://www.php.net/manual/en/language.types.string.php#91628
>

Hi, Peter!

> Also, as a side note, why does this hack below work?

It's not a hack. Variables, including callable ones with any arguments are
allowed to be interpolated. See another example: https://3v4l.org/BJUvL
--
Regards,
Valentin Udaltsov

---

## #123462 — tim@bastelstu.be — 2024-05-29T20:58:35+00:00

URL: https://externals.io/message/123362#123462 · In reply to: #123365

Hi


> In general, it would be nice to have some proper inline string
> templating, like other languages (js, C#, etc). At least some way to
> evaluate an expression and format. I'm thinking like in C#:
> 
> $"Price: {price:C2}, Quantity: {quantity}, Discount: {discount:P1},
> Total after discount: {(price * quantity * (1 - discount)):N2}"
> 
> Price is formatted using currency with 2 decimal places, discount is
> formatted using percentage and one decimal, and N is a number format
> with 2 decimals.

While I can get behind allowing arbitrary expressions for ease of use, 
the formatting suffixes you suggested effectively replicate what 
`sprintf` already does for you, just with an "incompatible syntax".

In fact for proper number and currency formatting you would likely need 
intl's MessageFormatter anyways, which already supports those kind of 
placeholders in a standardized fashion.

Best regards
Tim Düsterhus
