On Tue, Jul 14, 2026 at 7:31 PM Liam Hammett <[email protected]> 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.
