nititech / html-components
Write intuitive, reusable, class based HTML components
Requires
- php: >=7.0
README
A practical component system for PHP – write reusable, class-based UI components with props, children, and safe rendering.
Features
- Components as PHP classes
- Props and children
- Escaped-by-default output
- Self-closing and paired syntax
- No templating engine – 100% native PHP
Installation
composer require nititech/html-components
Usage
Creating components
Write components directly using native PHP syntax — similar to how JSX mixes HTML and logic:
<?php namespace components; class Message extends \HTML\Component { public function render() { $style = match ($this->variant) { 'success' => 'background-color: #e6ffed; color: #2f855a; border: 1px solid #c6f6d5;', 'error' => 'background-color: #ffe6e6; color: #c53030; border: 1px solid #feb2b2;', 'info' => 'background-color: #ebf8ff; color: #2b6cb0; border: 1px solid #bee3f8;', default => 'background-color: #f7fafc; color: #2d3748; border: 1px solid #e2e8f0;', }; ?> <div style="padding: 1rem; margin-bottom: 1rem; border-radius: 6px; <?= $style ?>"> <div style="font-weight: bold; margin-bottom: 0.5rem;"> <?= ucfirst($this->variant ?? 'Note') ?> 🔔 </div> <div> <?= $this->children ?> </div> </div> <?php } }
Rendering components
<?php $msg = new \components\Message(['variant' => 'success']); ?> Your profile was updated successfully.<br /> <a href="/cool">Continue</a> <?php $msg->close(); ?>
💡 More convenient component usage
We have written several plugins for Vite.
To use these components more convenient follow the guide of the vite-plugin-php-components plugin.
This plugin allows you to use these components as regular HTML elements and rewrites those up on compilation into real PHP calls:
<component.ButtonComponent class="btn-main">
Button Label
</component.ButtonComponent>
👇
<?php $c_234546546 = new \components\ButtonComponent(['class' => 'btn-main']); ?>
Button Label
<?php $c_234546546->close(); ?>
Alternative usage
Self-Closing Component
<?php \components\Example::closed(['foo' => 'bar', 'class' => 'test']); ?>
With JSON Props
<?php \components\Example::closed('{"foo":"bar","class":"test"}'); ?>
Output Modes
Components can either echo directly or return a string for further processing (e.g. passing into templates or APIs).
With closing tag
<?php $msg = new \components\Message(['variant' => 'success']); ?> Your profile was updated successfully.<br /> <a href="/cool">Continue</a> <?php $html = $msg->close(true); // Returns HTML string instead of echoing ?>
Self-closing
$html = \components\Message::closed( ['variant' => 'success', 'children' => 'Something went wrong.'], true, // Set last parameter to return as HTML string );
Notes
- HTML is written inline using regular PHP – no templating language required
<?= $this->children; ?>is unescaped inner content, other properties are escaped and can be safely used in the HTML context- You can mix control logic, conditions, and loops directly in PHP
Props & Escaping
| Access | Escaped? | Example |
|---|---|---|
$this->foo |
✅ Yes | Safe for direct HTML injection |
$this->__props__->safe('foo') |
✅ Yes | Safe for direct HTML injection |
$this->__props__->__toString() |
✅ Yes | Formatted and HTML-safe string of attributes, that can be directly injected into the attributes of an element. |
$this->__props__->foo or $this->__props__['foo'] |
❌ No | Use for raw values (e.g. JSON, IDs) |
$this->__props__->filter(['*', '!class']) |
❌ No | Use for getting an iterable array of raw values (e.g. to pass to child components) (excludes the children prop) |
$this->__props__->__toUnsafeString() |
❌ No | Formatted and not HTML-safe string of attributes, that can be printed into the attributes of a component. |
[...$this->__props__] |
❌ No | You can also spread the props into an array - those props are not HTML-safe! |
$this->children |
❌ No | Direct inner content (slot-like) |
Note: Only children is unescaped by default. All other props accessed as $this->prop_name are HTML-escaped for safety.
Utilities
Components
-
HTML.Element A ready-to-use component for rendering dynamic standard HTML elements with declarative props.
Usage:<HTML.Element element="button" type="submit" class="container"> Click me </HTML.Element>
or
<?php \HTML\Element::closed(['element' => 'img', 'src' => '/some-pic.jpg']); ?>
Props:
element: string (required) – the HTML tag to render (e.g., "div", "section", "button")- other attributes – pass-through attributes/handlers (style, class, data-, aria-, etc.)
Behavior:
- Renders a DOM element matching
element - Forwards additional props to the underlying element
- Keeps semantics and browser behavior of native HTML tags
Methods
-
\HTML\Utils::encode_output($input) Method to escape user-supplied or dynamic text before injecting it into HTML content, preventing XSS vulnerabilities.
Arguments:$input: mixed (required) – the data to escape
Behavior:
- Escapes supplied input
- If $input is an array it concatenates all elements to a single string
Issues
If you encounter any other bugs or need some other features feel free to open an issue.
Support
Love open source? Enjoying my project?
Your support can keep the momentum going! Consider a donation to fuel the creation of more innovative open source software.
| via Ko-Fi | Buy me a coffee | via PayPal |
|
|
|
|