PHP Single File Components: CSS, JS, and HTML sections in one .php file, Vue-SFC style, no build step.
<!--section::style-->
<style>.__self { padding: 1rem; }</style>
<!--section::output-->
<div class="__self">Hello, <?= htmlspecialchars($name) ?></div>$engine = new Phpsfc\Engine($componentsDir, $cacheDir);
echo $engine->render('widgets/hello', ['name' => 'World']);composer require dmvdigital/phpsfc
Requires PHP 8.1+.
For the full method reference, file-format grammar, caching internals, and security model, see DOCUMENTATION.md. Using an AI coding agent to write components? Point it at AGENTS.md first.
A component is referenced by its path, extension omitted, no separately invented name:
$engine->render('sections/hero-animated', ['title' => 'Hello']);
$engine->component('widgets/card')->set('title', 'Getting Started');A page needs a layout's shell but also needs to hand its own sections into that shell, that's what extends/load and slot()/block()/files() are for:
<!--extends::layout-->
<!--section::content-->
<div class="__self">page body</div><!--section::output-->
<head><?= $this->block('style') ?></head>
<body><?= $this->slot('content') ?></body>The setup section declares props once, and that single declaration drives both the runtime default and Editor Mode's control panel, no separate schema to keep in sync:
<!--section::setup-->
<?php
$setup->metadata('Hero Section')
->variable('title', ['default' => 'Welcome', 'control' => 'text']);Then open a standalone visual viewer (with a Monaco source editor a click away) for every component:
$engine->editor(); // dispatches based on $_GETRunnable, in examples/. Clone the repo, then:
php -S localhost:8000 -t examples/01-basic
...and open http://localhost:8000. Same pattern for any other example directory.
- 01-basic, render/load/extends, a setup schema, and a non-strict missing-component error.
- 02-layout, a page extending a layout and loading a widget component.
- 03-modifier, a custom modifier (CSS minification) and a custom
OutputStrategy, both registered under a key. - 04-vue-sfc, Vue x-template mode: two views compiled to
<script>templates, swapped by a hash router. - 05-php-logic, loops, conditionals, other plain PHP running inside sections, and
__DIR__reaching a sibling data file. - 06-css-file-cache, a modifier that writes bundled CSS to a file instead of inlining it.
- 07-auto-load, components discovered by being rendered from inside another component's output, not declared upfront.
- 08-content-blocks, CMS-style blocks in random order per request, with per-block styles injected into
<head>regardless of load order. - 09-file-modifiers, bundling both CSS and JS out to public files.
- 10-editor, Editor Mode's standalone visual viewer and Monaco source editor.
- 11-clear-cache,
cacheBuild()/cacheDelete()and their opt-in GET-triggered variants. - 12-conditional-slot,
hasSlot()picking a sidebar layout depending on what the page defines. - 13-autoload, explicit
<!--load::-->markers for shared components. - 14-component-and-assets, the
component()->set()OOP wrapper andasset()'s copy-if-stale + cache-busted URL. - 15-strict-props, strict mode (the default) throwing
MissingPropException/ComponentNotFoundExceptioninstead of soft-erroring. - 16-slot-content, passing pre-rendered markup into a component as a prop,
ob_start()/ob_get_clean()capturing a nestedrender()call.
MIT