Search by

fakis / light-dom

fakis

A lightweight, secure HTML DOM builder for PHP, with jQuery-style selectors and auto-escaping.

1.0.1 2026-09-22 00:37 UTC

This package is not auto-updated.

Last update: 2026-09-22 13:34:14 UTC


README

一个轻量、安全的 HTML DOM 构建器(PHP)。 用嵌套的 Dom 节点描述 HTML,自动输出经过正确转义、可靠的 HTML 字符串——附赠 jQuery 风格的选择器。

use Fakis\LightDom\Dom;

echo Dom::render(
    Dom::make('div#app.card[disabled]', ['data-id' => 1],
        Dom::make('h1.title', 'Hello & "World"'),
        Dom::trust('<i>icon</i>'),     // 受信任,不会被转义
    )
);

输出

<div id="app" class="card" disabled data-id="1">
    <h1 class="title">Hello &amp; &quot;World&quot;</h1>
    <i>icon</i>
</div>

特性

  • 默认安全 — 文本节点和属性值均经过 HTML 转义(ENT_QUOTES | ENT_HTML5);只有 Raw(通过 Dom::trust() 创建)会绕过转义,再也不怕意外 XSS。
  • jQuery 风格选择器div#id.classA.classB[attr=value][boolean-attr] 一口气解析成 Dom;只写 #id.class 时默认标签为 div
  • 可组合 — 每个节点就是一个纯 Dom 值对象(包含 tagattrschildren),递归构建,任意子树独立渲染。
  • 智能 class / style 处理 — 专用的 ClassesStyles 值对象,支持 attach / detach / patch 与自动去重,合并属性时不会丢失已有 class。
  • 组件支持 — 把 callable(Attrs, children): Dom 当作选择器传入,即可构建可复用组件。
  • Packagist 就绪 — PSR-4 自动加载,PHP 8.1+,MIT 协议,PHPUnit + GitHub Actions CI。

安装

composer require fakis/light-dom

要求

  • PHP 8.1+

使用

选择器语法

选择器生成的节点
div<div>
#app<div id="app"> (默认标签 = div)
.btn.large<div class="btn large">
a[href="/x"][target=_blank]<a href="/x" target="_blank">
input[type=text][required]<input type="text" required /> (void 元素)

属性与子节点

// 第一个额外参数若是关联数组,则视为属性
Dom::make('input', ['type' => 'text', 'value' => 'a&b']);

// 否则额外参数都是子节点
Dom::make('ul', Dom::make('li', 'one'), Dom::make('li', 'two'));

classstyle合并而非替换:

$attrs = new Attrs(['class' => 'a', 'style' => 'color:red']);
$attrs->attachClass('b c')->patchStyle('font-size:12px');
(string)$attrs; // class="a b c" style="color:red;font-size:12px;"

原始(受信任)HTML

Dom::make('div', Dom::trust($userProvidedMarkup)); // 不会被转义

Dom::trust() 仅用于你完全信任的内容。不可信输入必须作为普通字符串传入,将自动转义。

组件(可调用对象)

$card = function (Attrs $attrs, array $children) {
    return Dom::make('section.card', $attrs, ...$children);
};
Dom::make($card, ['data-x' => 1], Dom::make('p', 'body'));

全局辅助函数

echo dom('div#x.btn', 'Hi')->render(); // 等同于 Dom::make(...)
$attrs = attrs_merge(['class' => 'a', 'style' => 'color:red'], ['class' => 'b c']);
$classes = classes_attach('a b', 'd x');
$classes = classes_detach('a b', 'b c x');
$styles = styles_patch('display: none', 'font-size:12px', ['display' => 'block']);

架构

src/
├── Dom/                 # PSR-4 命名空间 Fakis\LightDom
│   ├── Classes.php      # class 属性集合(规范化、attach、detach)
│   ├── Styles.php       # style 属性集合(规范化、patch)
│   ├── Attrs.php        # 通用属性容器(委托给 class 与 style)
│   ├── Raw.php          # 标记:受信任、不转义的 HTML
│   └── Dom.php          # Dom 工厂方法、选择器解析、渲染器
└── helpers.php          # 全局 dom() 函数(autoload.files)
职责
Classes规范化 / 去重 / attach / detach CSS 类名
Styles规范化 / 合并 CSS 声明
Attrs统一的属性包;委托处理 classstyle
Rawreadonly 标记:选择不转义
Dom不可变 DOM 节点 + make() + render() + 选择器解析

开发

composer install
composer test              # 运行 PHPUnit
composer cs-check          # PSR-12 代码风格检查
composer cs-fix            # 自动修复

安全

所有动态内容默认都被转义。唯一的安全入口是 Dom::trust() / Raw,它被有意设计得非常显式,方便做 XSS 审查。

协议

MIT — 见 LICENSE