Re: [RFC] [Discussion] Native Markup Expressions
| From: | Garrett W. | Date: | Wed, 15 Jul 2026 00:33:07 +0000 |
| Subject: | Re: [RFC] [Discussion] Native Markup Expressions | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131926@lists.php.net to get a copy of this message | ||
On Tue, Jul 14, 2026 at 7:31 PM Liam Hammett
<liam+phpinternals@liamhammett.com> wrote:
>
> Hi internals,
>
> I'd like to open discussion on a new RFC, "Native Markup Expressions":
>
> RFC: https://wiki.php.net/rfc/native_markup_expressions
> Implementation (with tests):
> https://github.com/php/php-src/pull/22661
>
> It proposes a native syntax for HTML fragments as first-class PHP expressions,
> akin to how the frontend community has adopted JSX, with composition and
> escape-by-default output:
>
>
> class Greeting implements Markup\Html
> {
> public function __construct(public string $name) {}
>
> public function toHtml(): Markup\Html
> {
> return <>
> <h1 class="title">Hello, {$this->name}!</h1>
> <p>Welcome to PHP, where markup is a first-class
> expression.</p>
> </>;
> }
> }
>
> echo <Greeting name="Rasmus" />; // rendered HTML, values escaped
>
>
> Despite appearances, this is not a template language grafted onto the engine -
> the syntax is pure compile-time sugar. Every markup expression lowers
> during compilation to a plain
new expression:
>
>
> $html = <button class="btn">Sign in</button>;
> // compiles to exactly:
> $html = new \Markup\Element('button', ['class' => 'btn'],
> ['Sign in']);
>
>
> The RFC already answers many anticipated questions, and I am open
> to making further adjustments so this can become a feature the whole
> community benefits from.
>
> Looking forward to your feedback.
>
> Best regards,
> Liam
Cool! I'm reading through it now, and one thing gave me pause:
> Any tag whose name is capitalized, contains a namespace separator (), or names a static method
> (::) is a component; everything else is a literal HTML element.
Not so sure about that heuristic. PSR-4 is not a binding standard on
the language; class names can be lowercase, and therefore should be
valid as a component name. Instead of looking at whether the tag name
is capitalized, I'd think it would be better handled using the
standard fallback resolution strategy: look in the current namespace,
then look at imports, then global/root namespace, and only then
fallback to a literal HTML tag.
--
Garrett W.