Inline conditional that returns null if falsy

php.internals

David Rodrigues

5 years ago
Hello! It is just a suggestion to be discussed. A lot of places on my projects I have codes like: $companies = $user->companies->count() ? new Collection($user->companies) : null; So $companies will be null except if the user has companies. My suggestion is create some kind of inline conditional to works like that: $companies = $user->companies->count() => new Collection($user->companies); If the conditional ($user->companies->count()) is true, then will return the value (after =>), else will be null. In my current work project, I have more than 100+ occurrences like that. So some more examples: $userCategory ? $userCategory->getTitle() : null -> It could be optimized to the new nullsafe operator $userCategory?->getTitle() return $languageFirst instanceof LanguageExperience ? $languageFirst->title : null; -> This not, with my suggestion we have: return $languageFirst instanceof LanguageExperience => $languageFirst->title; The => is just a suggestion, other options using existing keywords is: return expr() then output(); return expr(): output(); I do not know if other languages support something like that. Thanks! Atenciosamente, David Rodrigues

Ben Ramsey

5 years ago
> The => is just a suggestion, other options using existing keywords is: > return expr() then output(); > return expr(): output(); > > I do not know if other languages support something like that.
I think it might be a good idea to check other languages to see if they support something like this. We could use their examples as points of reference for discussing whether to include this functionality in PHP. Cheers, Ben

Michael Morris

5 years ago
Javascript has this now though support isn't widespread. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining The most similar way to do it in PHP would be ?-> On Fri, Feb 12, 2021 at 1:46 PM Ben Ramsey <ben@benramsey.com> wrote:

David Rodrigues

5 years ago
Em qua., 24 de fev. de 2021 às 12:29, Michael Morris <tendoaki@gmail.com> escreveu:
> Javascript has this now though support isn't widespread. > > > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining > > The most similar way to do it in PHP would be ?-> >
Optional chaining is not the same. My suggestion is similar to: $variable = $user->exists ? $user->fullname; // suggestion (will return null if expression is falsy) $variable = $user->exists ? $user->fullname : null; // same as Optional chaining is: $variable = $user?->exists; // PHP 8 $variable = $user && $user->exists ? true : null; // same as

Marco Pivetta

5 years ago
Hey David, On Fri, Feb 12, 2021, 20:24 David Rodrigues <david.proweb@gmail.com> wrote:
> Hello! > > It is just a suggestion to be discussed. > > A lot of places on my projects I have codes like: > > $companies = $user->companies->count() > ? new Collection($user->companies) > : null; >
Even upfront, this looks like a quite bad idea: either you have an empty collection, or you have a collection with elements in it, but `null` is a very different concept that isn't homogeneous with the resulting type. I've updated multiple projects in the past where `array|null` was used as return type for a collection-alike endpoint, removing `null` and replacing it with an empty iterable instead.

David Rodrigues

5 years ago
Em sáb., 13 de fev. de 2021 às 00:11, Marco Pivetta <ocramius@gmail.com> escreveu:
> Hey David, > > Even upfront, this looks like a quite bad idea: either you have an empty > collection, or you have a collection with elements in it, but `null` is a > very different concept that isn't homogeneous with the resulting type. > > I've updated multiple projects in the past where `array|null` was used as > return type for a collection-alike endpoint, removing `null` and replacing > it with an empty iterable instead. >
This was just one of the examples I have, but I still think it is valid. Creating an empty collection costs resources that could be avoided in situations where null could be used (as is most of my real use cases). But there are other situations where we can use different situations to use this type of resource. One of the examples I have is when I need to include a class in an HTML element conditionally. There are probably better ways, but this is a quick one for simple situations: <div class="user {{ $user => "online" }}">...</div> vs. <div class="user {{ $user ? "online" : null }}">...</div> It is much easier to read, and I believe that the cost for language would be minimal, and perhaps even more optimized than the use of ?:. Atenciosamente, David Rodrigues Em sáb., 13 de fev. de 2021 às 00:11, Marco Pivetta <ocramius@gmail.com> escreveu:

Nikita Popov

5 years ago
On Fri, Feb 12, 2021 at 8:25 PM David Rodrigues <david.proweb@gmail.com> wrote:
> Hello! > > It is just a suggestion to be discussed. > > A lot of places on my projects I have codes like: > > $companies = $user->companies->count() > ? new Collection($user->companies) > : null; > > So $companies will be null except if the user has companies. > > My suggestion is create some kind of inline conditional to works like that: > > $companies = $user->companies->count() => new Collection($user->companies); > > If the conditional ($user->companies->count()) is true, then will return > the value (after =>), else will be null. > > In my current work project, I have more than 100+ occurrences like that. > > So some more examples: > > $userCategory ? $userCategory->getTitle() : null > -> It could be optimized to the new nullsafe operator > $userCategory?->getTitle() > > return $languageFirst instanceof LanguageExperience > ? $languageFirst->title : null; > -> This not, with my suggestion we have: > return $languageFirst instanceof LanguageExperience => > $languageFirst->title; > > The => is just a suggestion, other options using existing keywords is: > return expr() then output(); > return expr(): output(); > > I do not know if other languages support something like that. > > Thanks! >
There's a limited budget for this kind of syntax sugar, and we already have ?:, ??, ??=, ?->. I don't think there's space for yet another shorthand conditional syntax. Note that => cannot be used for this purpose, as it is already used for array literals. Regards, Nikita

Guilliam Xavier

5 years ago
Hi, On Fri, Feb 12, 2021 at 8:45 PM Ben Ramsey <ben@benramsey.com> wrote:
> > I think it might be a good idea to check other languages to see if they > support something like this. We could use their examples as points of > reference for discussing whether to include this functionality in PHP. >
On Sat, Feb 13, 2021 at 5:22 PM David Rodrigues <david.proweb@gmail.com> wrote:
> > One of the examples I have is when I need to include a class in an HTML > element conditionally. There are probably better ways, but this is a quick > one for simple situations: > > <div class="user {{ $user => "online" }}">...</div> vs. > <div class="user {{ $user ? "online" : null }}">...</div> >
On Tue, Feb 23, 2021 at 3:31 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> > There's a limited budget for this kind of syntax sugar, and we already have > ?:, ??, ??=, ?->. I don't think there's space for yet another shorthand > conditional syntax. > > Note that => cannot be used for this purpose, as it is already used for > array literals. >
In Twig <https://en.wikipedia.org/wiki/Twig_(template_engine)>, the "else" part of a ternary expression is optional (colon included) and defaults to an empty string. So, the following two lines are equivalent: <div class="user {{ user ? 'online' }}">...</div> <div class="user {{ user ? 'online' : '' }}">...</div> Maybe PHP could do the same (with `null` rather than an empty string for the default), i.e.: var_dump(true ? 'foo'); // string(3) "foo" var_dump(false ? 'foo'); // NULL but I'm not sure if the added complexity (in parser implementation and in the language) would be worth it, to avoid typing " : null", nor if everyone would actually find the shorthand more readable?
-- Guilliam Xavier

Chase Peeler

5 years ago
On Tue, Feb 23, 2021 at 9:31 AM Nikita Popov <nikita.ppv@gmail.com> wrote:
> On Fri, Feb 12, 2021 at 8:25 PM David Rodrigues <david.proweb@gmail.com> > wrote: > > > Hello! > > > > It is just a suggestion to be discussed. > > > > A lot of places on my projects I have codes like: > > > > $companies = $user->companies->count() > > ? new Collection($user->companies) > > : null; > > > > So $companies will be null except if the user has companies. > > > > My suggestion is create some kind of inline conditional to works like > that: > > > > $companies = $user->companies->count() => new > Collection($user->companies); > > > > If the conditional ($user->companies->count()) is true, then will return > > the value (after =>), else will be null. > > > > In my current work project, I have more than 100+ occurrences like that. > > > > So some more examples: > > > > $userCategory ? $userCategory->getTitle() : null > > -> It could be optimized to the new nullsafe operator > > $userCategory?->getTitle() > > > > return $languageFirst instanceof LanguageExperience > > ? $languageFirst->title : null; > > -> This not, with my suggestion we have: > > return $languageFirst instanceof LanguageExperience => > > $languageFirst->title; > > > > The => is just a suggestion, other options using existing keywords is: > > return expr() then output(); > > return expr(): output(); > > > > I do not know if other languages support something like that. > > > > Thanks! > > > > There's a limited budget for this kind of syntax sugar, and we already have > ?:, ??, ??=, ?->. I don't think there's space for yet another shorthand > conditional syntax. > >
I don't really have any strong feelings on this either way, but ?! seems like a logical choice if it was to be implemented.
> Note that => cannot be used for this purpose, as it is already used for > array literals. > > Regards, > Nikita >
-- Chase Peeler chasepeeler@gmail.com

Albert Casademont Filella

5 years ago
Another example is when a scalar input needs to be either left null or converted to a Value Object: $color = $data['color'] ? new Color($data['color']) : null; This would become; $color = $data['color'] ? new Color($data['color']); //the ": null" part is implicit It's actually kinda the inverse of the "?:" operator. As Guilliam said, Twig already implements such behaviour, it's quite handy when dealing with nullable variables, On Tue, Feb 23, 2021 at 4:26 PM Chase Peeler <chasepeeler@gmail.com> wrote:

Larry Garfield

5 years ago
On Tue, Feb 23, 2021, at 10:49 AM, Albert Casademont wrote:
> Another example is when a scalar input needs to be either left null or > converted to a Value Object: > > $color = $data['color'] ? new Color($data['color']) : null; > > This would become; > > $color = $data['color'] ? new Color($data['color']); //the ": null" part is > implicit > > It's actually kinda the inverse of the "?:" operator. > > As Guilliam said, Twig already implements such behaviour, it's quite handy > when dealing with nullable variables,
1) Please don't top post. 2) The advantage of ?: over long-ternary is that the part it lets you omit is of variable size, and is often verbose (nested array elements). That's not the case here, as the omitted portion is a fixed length short constant value (": null"). So the value of the abbreviation is much less. I am also not a fan of null being commonly used, as it is a dangerous value. More often I would not want null if the color were missing but some default color value, which would be represented by something other than null anyway. And "falsy" is, as we've been reminded numerous times, a dangerous and tricky thing. (I just had several PRs against one of my OSS libraries because it relied on falsy, which had all sorts of incorrect failure conditions.) I'd be a -1 here. --Larry Garfield

Guilliam Xavier

5 years ago
On Tue, Feb 23, 2021 at 6:28 PM Larry Garfield <larry@garfieldtech.com> wrote:
> On Tue, Feb 23, 2021, at 10:49 AM, Albert Casademont wrote: > > Another example is when a scalar input needs to be either left null or > > converted to a Value Object: > > > > $color = $data['color'] ? new Color($data['color']) : null; > > > > This would become; > > > > $color = $data['color'] ? new Color($data['color']); //the ": null" part > is > > implicit > > > > It's actually kinda the inverse of the "?:" operator. > > > > As Guilliam said, Twig already implements such behaviour, it's quite > handy > > when dealing with nullable variables, > > 1) Please don't top post. > > 2) > > The advantage of ?: over long-ternary is that the part it lets you omit is > of variable size, and is often verbose (nested array elements).
For completeness: it's also important when implying side effects, e.g. `foo() ?: bar()` calls foo() only once, while `foo() ? foo() : bar()` may twice. That's not the case here, as the omitted portion is a fixed length short
> constant value (": null"). So the value of the abbreviation is much less. >
Indeed, and (as I said too) I'm not even sure whether it improves readability or instead worsens it. (By the way, I mentioned Twig because David's HTML example (Smarty maybe?) reminded me of it, but that's a "template engine"; I actually don't know a "general purpose" programming language with a C-like ternary operator that allows omitting the ": null" part.)
> > I am also not a fan of null being commonly used, as it is a dangerous > value. More often I would not want null if the color were missing but some > default color value, which would be represented by something other than > null anyway.
You seem to join Marco here ;) And "falsy" is, as we've been reminded numerous times, a dangerous and
> tricky thing. (I just had several PRs against one of my OSS libraries > because it relied on falsy, which had all sorts of incorrect failure > conditions.) >
I would just add that it's also true for "?:" (i.e. not specific to the suggestion at hand, although the lack of a non-controversial example so far may be a hint)
> > I'd be a -1 here. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
-- Guilliam Xavier

Albert Casademont Filella

5 years ago
On Tue, Feb 23, 2021 at 6:28 PM Larry Garfield <larry@garfieldtech.com> wrote:
> > 1) Please don't top post. >
Sorry for that!
> 2) > > The advantage of ?: over long-ternary is that the part it lets you omit is > of variable size, and is often verbose (nested array elements). That's not > the case here, as the omitted portion is a fixed length short constant > value (": null"). So the value of the abbreviation is much less. >
Sure, it's not a big deal having to write the ": null" but it doesn't add any value
> > I am also not a fan of null being commonly used, as it is a dangerous > value. More often I would not want null if the color were missing but some > default color value, which would be represented by something other than > null anyway. And "falsy" is, as we've been reminded numerous times, a > dangerous and tricky thing. (I just had several PRs against one of my OSS > libraries because it relied on falsy, which had all sorts of incorrect > failure conditions.) >
Agreed, it was just the first example that came to my mind, probably not the best one. A better example would creating UUID VO's from string|null input, there's little room for a default here.

Rowan Collins

5 years ago
On 23/02/2021 18:41, Albert Casademont wrote:
> Sure, it's not a big deal having to write the ": null" but it doesn't add > any value
On the contrary, it adds an important piece of information: that the default value is "null", rather than "false", or "0", or "new EmptyValue()". For instance, it doesn't seem at all obvious to me that this code should produce a null: $items = []; $itemCount = $items ? count($items); I might be more convinced that "null" is the "natural" value if the left-hand operand was only checked against null, not "falsiness": in that case, you can read it as "if it's null, leave it alone". I'd still be inclined towards "too specific to use up more syntax", though.
> A better example would creating UUID VO's from string|null > input, there's little room for a default here.
I'm not quite sure what process you're describing, but any of the following seem equally reasonable: $nullableUuid = is_null($input) ? UUID::for($input) : null; $maybeNilUuid = is_null($input) ? UUID::for($input) : UUID:nilValue(); $definitelyUuid = is_null($input) ? UUID::for($input) : UUID:random(); Syntax for skipping the is_null/isset on the left would be higher up my wish list than syntax for skipping the :null on the right. Regards,
-- Rowan Tommins [IMSoP]

Sara Golemon

5 years ago
On Tue, Feb 23, 2021 at 1:05 PM Rowan Tommins <rowan.collins@gmail.com> wrote:
> > On 23/02/2021 18:41, Albert Casademont wrote: > > Sure, it's not a big deal having to write the ": null" but it doesn't
add
> > any value > > On the contrary, it adds an important piece of information: that the > default value is "null", rather than "false", or "0", or "new
EmptyValue()".
> > For instance, it doesn't seem at all obvious to me that this code should > produce a null: > > $items = []; > $itemCount = $items ? count($items); > > I might be more convinced that "null" is the "natural" value if the > left-hand operand was only checked against null, not "falsiness": in > that case, you can read it as "if it's null, leave it alone". I'd still > be inclined towards "too specific to use up more syntax", though. >
This sums up my feelings on the topic very well. The proposal seeks to remove clarity of intent to save four characters. Hard nope as presented. -Sara

Mike Schinkel

5 years ago
> On Feb 23, 2021, at 2:05 PM, Rowan Tommins <rowan.collins@gmail.com> wrote: > > On 23/02/2021 18:41, Albert Casademont wrote: >> Sure, it's not a big deal having to write the ": null" but it doesn't add >> any value > > > On the contrary, it adds an important piece of information: that the default value is "null", rather than "false", or "0", or "new EmptyValue()". > For instance, it doesn't seem at all obvious to me that this code should produce a null: > > $items = []; > $itemCount = $items ? count($items); > > I might be more convinced that "null" is the "natural" value if the left-hand operand was only checked against null, not "falsiness": in that case, you can read it as "if it's null, leave it alone". I'd still be inclined towards "too specific to use up more syntax", though.
If you look at it from a software engineering perspective — which is how I assume most on this thread have been looking at it — being more explicit in the code is probably a better practice than saving a few keystrokes. OTOH, if you view it from the perspective of a *templating* language — which is what PHP was initially created to be, for the web — then the reduction in visual noise from omitting ": null" would be a nice plus. And in the case of templating, the distinction between null vs. false vs. "" would be completely moot. Repeating code similar to that from the message sent by David Rodrigues you can see that eliminating the ": null" is less noisy: <div class="user <?php user ? 'online' : null ?>">...</div> <div class="user <?php user ? 'online' ?>">...</div> Although one ":null" eliminated is not that significant, PHP templates for generating HTML are notorious for having conditionals littered throughout, with tens if not hundreds of cases per file. So being able to drop the ":null" would be a really nice addition for templating. To emphasize this feature address templating use-cases one might argue that dropping the "or" case of the trinary might only be supported when between single-line "<?php" and "?>" delimiters. -Mike P.S. Of course making it work differently between single-line delimiters and elsewhere would create inconsistency in the language so I probably would not actually argue that, I was just trying to make a rhetorical point.

Chase Peeler

5 years ago
On Tue, Feb 23, 2021 at 11:27 PM Mike Schinkel <mike@newclarity.net> wrote:
> > On Feb 23, 2021, at 2:05 PM, Rowan Tommins <rowan.collins@gmail.com> > wrote: > > > > On 23/02/2021 18:41, Albert Casademont wrote: > >> Sure, it's not a big deal having to write the ": null" but it doesn't > add > >> any value > > > > > > On the contrary, it adds an important piece of information: that the > default value is "null", rather than "false", or "0", or "new EmptyValue()". > > For instance, it doesn't seem at all obvious to me that this code should > produce a null: > > > > $items = []; > > $itemCount = $items ? count($items); > > > > I might be more convinced that "null" is the "natural" value if the > left-hand operand was only checked against null, not "falsiness": in that > case, you can read it as "if it's null, leave it alone". I'd still be > inclined towards "too specific to use up more syntax", though. > > If you look at it from a software engineering perspective — which is how I > assume most on this thread have been looking at it — being more explicit in > the code is probably a better practice than saving a few keystrokes. > > OTOH, if you view it from the perspective of a *templating* language — > which is what PHP was initially created to be, for the web — then the > reduction in visual noise from omitting ": null" would be a nice plus. And > in the case of templating, the distinction between null vs. false vs. "" > would be completely moot. > >
But PHP isn't just a templating language anymore. If PHP currently had support for omitting the third argument on the ternary operator, then I'd be against changes that required it given the BC implications. I think just dropping the need for a third argument on the existing ternary operator is a bad idea. I'm ambivalent when it comes to creating a new symbol to support this behavior (e.g. ?!). I don't really think it's necessary, but, I don't think it hurts anything either.
> Repeating code similar to that from the message sent by David Rodrigues > you can see that eliminating the ": null" is less noisy: > > <div class="user <?php user ? 'online' : null ?>">...</div> > <div class="user <?php user ? 'online' ?>">...</div> > > Although one ":null" eliminated is not that significant, PHP templates > for generating HTML are notorious for having conditionals littered > throughout, with tens if not hundreds of cases per file. So being able to > drop the ":null" would be a really nice addition for templating. > > To emphasize this feature address templating use-cases one might argue > that dropping the "or" case of the trinary might only be supported when > between single-line "<?php" and "?>" delimiters. > > -Mike > > P.S. Of course making it work differently between single-line delimiters > and elsewhere would create inconsistency in the language so I probably > would not actually argue that, I was just trying to make a rhetorical point. > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
-- Chase Peeler chasepeeler@gmail.com

Mike Schinkel

5 years ago
> On Feb 24, 2021, at 11:27 AM, Chase Peeler <chasepeeler@gmail.com> wrote: > > On Tue, Feb 23, 2021 at 11:27 PM Mike Schinkel <mike@newclarity.net <mailto:mike@newclarity.net>> wrote: > > On Feb 23, 2021, at 2:05 PM, Rowan Tommins <rowan.collins@gmail.com <mailto:rowan.collins@gmail.com>> wrote: > > > > On 23/02/2021 18:41, Albert Casademont wrote: > >> Sure, it's not a big deal having to write the ": null" but it doesn't add > >> any value > > > > > > On the contrary, it adds an important piece of information: that the default value is "null", rather than "false", or "0", or "new EmptyValue()". > > For instance, it doesn't seem at all obvious to me that this code should produce a null: > > > > $items = []; > > $itemCount = $items ? count($items); > > > > I might be more convinced that "null" is the "natural" value if the left-hand operand was only checked against null, not "falsiness": in that case, you can read it as "if it's null, leave it alone". I'd still be inclined towards "too specific to use up more syntax", though. > > If you look at it from a software engineering perspective — which is how I assume most on this thread have been looking at it — being more explicit in the code is probably a better practice than saving a few keystrokes. > > OTOH, if you view it from the perspective of a *templating* language — which is what PHP was initially created to be, for the web — then the reduction in visual noise from omitting ": null" would be a nice plus. And in the case of templating, the distinction between null vs. false vs. "" would be completely moot. > > > But PHP isn't just a templating language anymore.
It is not? If it is not I think a lot of userland PHP developers never got that decree.
> If PHP currently had support for omitting the third argument on the ternary operator, then I'd be against changes that required it given the BC implications.
Can you elaborate on those?

Rowan Collins

5 years ago
On 24/02/2021 04:26, Mike Schinkel wrote:
> Repeating code similar to that from the message sent by David Rodrigues you can see that eliminating the ": null" is less noisy: > > <div class="user <?php user ? 'online' : null ?>">...</div> > <div class="user <?php user ? 'online' ?>">...</div>
That's an interesting use case. Of course, the logical default there is actually '' (empty string) rather than null, since "echo null;" doesn't actually make much sense, but null works under current type juggling rules. Then again, perhaps this is a good example of why PHP *isn't* the best choice any more if you want a templating language. Twig, for instance, has exactly this facility [https://twig.symfony.com/doc/3.x/templates.html#other-operators]: {{ foo ? 'yes' : 'no' }} {{ foo ?: 'no' }}is the same as {{ foo ? foo : 'no' }} {{ foo ? 'yes' }}is the same as {{ foo ? 'yes' : '' }} If we wanted to close the gap between Twig and plain PHP for templating, this might be somewhere on the list, but after more significant features like automatic escaping, filter / pipe syntax, etc. Regards,
-- Rowan Tommins [IMSoP]

Kingsquare.nl - Robin Speekenbrink

5 years ago
Op do 25 feb. 2021 om 09:55 schreef Rowan Tommins <rowan.collins@gmail.com>:
> On 24/02/2021 04:26, Mike Schinkel wrote: > > Repeating code similar to that from the message sent by David Rodrigues > you can see that eliminating the ": null" is less noisy: > > > > <div class="user <?php user ? 'online' : null ?>">...</div> > > <div class="user <?php user ? 'online' ?>">...</div> > >
Also just to have a somewhat apples to apples (working) comparission, it would read something like: <div class="user <?php echo user ? 'online' : null ?>">...</div> <div class="user <?php echo user ? 'online' ?>">...</div> or one of the other possibilities (print / <?= ) and with the addition of those extra strokes i fail to see the cleanliness over the added obtrusion of `the one way`: <div class="user <?= user ? 'online' : '' ?>">...</div> this atleast is consistent, doesn't provide yet another way of doing the same thing and even allows for easier refactoring (i.e. if the falsy situation has to change from '' to 'offline') to summarize from my 2cent userland developer standpoint: Hope this doesn't make this in... (or is at least strongly discouraged) Thanks, Robin

Larry Garfield

5 years ago
On Thu, Feb 25, 2021, at 2:55 AM, Rowan Tommins wrote:
> On 24/02/2021 04:26, Mike Schinkel wrote: > > Repeating code similar to that from the message sent by David Rodrigues you can see that eliminating the ": null" is less noisy: > > > > <div class="user <?php user ? 'online' : null ?>">...</div> > > <div class="user <?php user ? 'online' ?>">...</div> > > > That's an interesting use case. Of course, the logical default there is > actually '' (empty string) rather than null, since "echo null;" doesn't > actually make much sense, but null works under current type juggling rules. > > Then again, perhaps this is a good example of why PHP *isn't* the best > choice any more if you want a templating language. Twig, for instance, > has exactly this facility > [https://twig.symfony.com/doc/3.x/templates.html#other-operators]:
Given the security implications of plain PHP templating (you're on your own for absolutely all filtering and escaping, good luck), I'd say this isn't even a controversial statement. PHP may have begun life as a templating language for the 90s, but in the 2020s it's a fairly mediocre option at best compared to what else is readily available. --Larry Garfield