Search by

cloud-castle / html-builder

alex-4-17

Объектная модель HTML+CSS+JS для PHP 8.1+: класс на каждый DOM-элемент, объекты атрибутов, стилей, событий и значений, цепочки методов (fluent), генерация и разбор HTML, CSS и JavaScript, CSS-селекторы и обход дерева, минификация и форматирование, потоковый рендеринг на генераторах. Безопасно по умо

v1.0.1 2026-09-27 21:43 UTC

This package is auto-updated.

Last update: 2026-09-28 00:28:05 UTC


README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle HtmlBuilder

CloudCastle HtmlBuilder

Пакет собирает и разбирает HTML, CSS и JavaScript через объектную модель, в которой объектом является каждый элемент, атрибут, свойство стиля, значение и событие.

Пакет

Packagist Загрузки Версия PHP Лицензия

Репозитории

GitVerse Сборка Документация Сайт Задачи Релизы

Качество кода

PHPStan Psalm PHPMD PHPCS Покрытие Infection MSI OpenSSF Scorecard

Установка

composer require cloud-castle/html-builder

Требуется PHP 8.1+ и расширения json, mbstring. Никаких других расширений не нужно: разбор HTML, CSS и JavaScript выполняется на чистом PHP, поэтому пакет работает одинаково на любом хостинге и в любом контейнере.

Быстрый старт

<?php

use CloudCastle\HtmlBuilder\Html;
use CloudCastle\HtmlBuilder\Css\Value\Color;
use CloudCastle\HtmlBuilder\Event\Event;
use CloudCastle\HtmlBuilder\Event\Handler\CallHandler;

$card = Html::div()->id('карточка')->addClass('card')
    ->style(['display' => 'flex', 'gap' => '1rem'])
    ->title('Товар из каталога')
    ->append(
        Html::img()->src('/изображения/товар.png')->alt('Товар')->loading('lazy'),
        Html::h2()->addClass('card__title')->text('Кофемолка'),
        Html::span()->addClass('card__price')->style(['color' => Color::hex('#2f6f3e')])->text('4 900 ₽'),
        Html::button()->type('button')
            ->on(Event::click(CallHandler::of('cart.add', 17)))
            ->text('В корзину'),
    );

echo $card->render();
<div class="card" id="карточка" title="Товар из каталога" style="display: flex; gap: 1rem"><img src="/изображения/товар.png" alt="Товар" loading="lazy"><h2 class="card__title">Кофемолка</h2><span class="card__price" style="color: #2f6f3e">4 900 ₽</span><button type="button" onclick="cart.add(17)">В корзину</button></div>

Разбор работает в обе стороны: разметку можно прочитать, обойти селекторами, изменить и снова вывести.

$document = Html::fromFile('страница.html');

foreach ($document->querySelectorAll('ul.catalog > li.item > a') as $link) {
    $link->attr('rel', 'nofollow')->addClass('external');
}

echo $document->render(RenderOptions::pretty());

Возможности

  • Объектная модель документа. Отдельный класс на каждый из 211 тегов разметки, у каждого — типизированные методы своих атрибутов и общий набор глобальных атрибутов.
  • Атрибут — объект. Обычный, логический, перечислимый, адресный, набора данных, доступности, класса, стиля и обработчика события: каждый вид знает свои правила вывода и проверки.
  • Стили объектами. 187 типизированных методов свойств, значения-объекты (цвет, размер, функция, переменная, список), управляющие правила @media, @supports, @font-face, @keyframes, раскрытие и сворачивание сокращённых свойств.
  • JavaScript объектами. Инструкции и выражения, литералы, обращения, вызовы, стрелочные функции, обработчики событий и сжатие кода с учётом автоматической расстановки точек с запятой, объединение файлов и карта кода Source Map v3.
  • Разбор без расширений. HTML, CSS и JavaScript читаются на чистом PHP с восстановлением незакрытых тегов, неявным закрытием и пределами длины и вложенности.
  • Выборка по селекторам CSS и по XPath. Комбинаторы >, +, ~, позиционные псевдоклассы, :has(), :is(), :where(), :not(), состояния формы, селекторы атрибутов и расчёт специфичности; рядом — подмножество XPath с осями, предикатами и чтением значений атрибутов, тоже без ext-dom.
  • Безопасность по умолчанию. Экранирование по контексту, белые списки схем адресов, очистка недоверенной разметки, запрет expression() и javascript: в стилях, пределы против разметки-бомбы.
  • Доводка пользовательского содержимого. Абзацы из переводов строк, ссылки вместо адресов в тексте, приведение адресов к абсолютным и пометка внешних ссылок.
  • Потоковая выборка. Селектор применяется прямо к потоку лексем: совпадения находятся без построения дерева — быстрее, чем по дереву, и с расходом памяти, не зависящим от документа.
  • Потоковый вывод. Разметка отдаётся генератором, потоковый писатель и потоковая очистка работают без построения дерева: расход памяти не зависит от размера документа.
  • Перенос между процессами. Дерево сериализуется в JSON, XML и YAML и восстанавливается обратно.

Полный список — в каталоге возможностей: страница на каждую из 66 возможностей с примером, который сверяется исполнением при каждой сборке, сравнением с аналогами и схемой места возможности в работе пакета.

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически из честных сравнительных тестов (composer docs:compare) на ОДИНАКОВОЙ операции для всех аналогов, PHP 8.1.34, без Xdebug. Перечень возможностей — объединение наборов всех десяти пакетов, а не только сильные стороны этого.

1. Функциональность

Возможность🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Построение разметки
Объектная модель документа с деревом узлов✅✅✅⚠️ dom✅⚠️ dom❌❌❌❌
Отдельный класс на каждый тег разметки (211 тегов)✅❌⚠️ частично❌❌❌❌❌❌❌
Типизированные методы атрибутов у каждого элемента✅❌⚠️ частично❌❌❌❌❌❌❌
Глобальные атрибуты отдельными методами✅❌⚠️ частично❌❌❌❌❌❌❌
Атрибут — объект (логический, перечислимый, адресный, данные, aria)✅❌❌❌❌❌❌❌❌❌
Потоковая запись разметки без дерева узлов✅❌❌❌❌❌❌❌❌❌
Вывод генератором (потоковая отдача частями)✅❌❌❌❌❌❌❌❌❌
Форматированный вывод с отступами✅❌❌✅✅❌✅❌❌❌
Сборка документа с каркасом (html, head, body)✅❌❌✅✅❌❌❌❌❌
Копирование поддерева (глубокая копия)✅✅❌⚠️ dom✅❌❌❌❌❌
Разбор разметки
Разбор HTML без расширения ext-dom✅❌❌❌❌❌❌✅❌❌
Потоковый токенизатор (генератор лексем)✅❌❌❌❌❌❌❌❌❌
Восстановление незакрытых и перекрёстных тегов✅❌❌✅✅✅❌✅✅❌
Неявное закрытие тегов (li, td, p)✅❌❌✅✅✅❌✅✅❌
Сырой текст script, style, textarea, title✅❌❌✅✅✅❌✅✅❌
Пределы длины и вложенности против разметки-бомбы✅❌❌❌❌❌❌✅✅❌
Позиция ошибки (строка и столбец) в сообщении✅❌❌✅❌❌✅❌❌❌
Разбор фрагмента и документа по отдельности✅❌❌✅✅✅❌❌❌❌
Раскодирование ссылок на символы при разборе✅❌❌✅✅✅❌✅✅❌
Выборка и обход
Выборка по селекторам CSS✅❌❌⚠️ xpath✅✅❌❌❌❌
Комбинаторы >, +, ~ и вложенные списки селекторов✅❌❌❌⚠️ частично✅❌❌❌❌
Позиционные псевдоклассы (nth-child, nth-of-type)✅❌❌❌⚠️ частично✅❌❌❌❌
Псевдоклассы :has(), :is(), :where(), :not()✅❌❌❌❌⚠️ частично❌❌❌❌
Псевдоклассы состояния формы (:checked, :required)✅❌❌❌❌❌❌❌❌❌
Селекторы атрибутов со всеми операторами и флагом i✅❌❌❌⚠️ частично✅❌❌❌❌
Ленивый обход дерева генератором✅❌❌❌❌❌❌❌❌❌
Расчёт специфичности селектора✅❌❌❌❌❌❌❌❌❌
Поиск ближайшего предка по селектору (closest)✅❌❌❌❌⚠️ частично❌❌❌❌
Выборка по записи XPath без расширения ext-dom✅❌❌⚠️ dom⚠️ dom⚠️ dom❌❌❌❌
Чтение значений атрибутов записью XPath✅❌❌⚠️ dom⚠️ dom⚠️ dom❌❌❌❌
Выборка по селектору без построения дерева✅❌❌❌❌❌❌❌❌❌
Значения, текст и разметка совпадений потоком✅❌❌❌❌❌❌❌❌❌
CSS
Объектная модель таблицы стилей✅❌❌❌❌❌✅❌❌❌
Типизированные методы на каждое свойство (187)✅❌❌❌❌❌❌❌❌❌
Значения-объекты: цвет, размер, функция, переменная✅❌❌❌❌❌⚠️ частично❌❌❌
Управляющие правила (@media, @supports, @font-face)✅❌❌❌❌❌✅❌❌❌
Разбор записи цвета и перевод между форматами✅❌❌❌❌❌⚠️ частично❌❌❌
Контраст и относительная яркость цвета✅❌❌❌❌❌❌❌❌❌
Сжатие таблицы стилей✅❌❌❌❌❌✅❌❌✅
Отбор правил по элементу с учётом специфичности✅❌❌❌❌❌❌❌❌❌
Раскрытие и сворачивание сокращённых свойств✅❌❌❌❌❌⚠️ устарело❌❌❌
JavaScript
Объектная модель кода (инструкции и выражения)✅❌❌❌❌❌❌❌❌❌
Разбор кода в объектную модель✅❌❌❌❌❌❌❌❌❌
Сжатие кода с учётом автоматических точек с запятой✅❌❌❌❌❌❌❌❌⚠️ без разбора
Обработчики событий как объекты✅❌❌❌❌❌❌❌❌❌
Безопасная передача данных PHP в код (литералы)✅✅⚠️ частично❌❌❌❌❌❌❌
Объединение файлов кода при сжатии✅❌❌❌❌❌❌❌❌✅
Карта кода для сжатых скриптов✅❌❌❌❌❌❌❌❌❌
Безопасность
Экранирование по контексту (текст, атрибут, CSS, JS, URL)✅⚠️ частично⚠️ частично⚠️ частично❌❌❌⚠️ частично⚠️ частично❌
Белый список схем адресов✅❌❌❌❌❌❌✅✅❌
Очистка разметки по белым спискам✅❌❌❌❌❌❌✅✅❌
Потоковая очистка без дерева✅❌❌❌❌❌❌❌❌❌
Отбор свойств инлайнового стиля при очистке✅❌❌❌❌❌❌✅❌❌
Запрет выражений CSS и адресов javascript: в стилях✅❌❌❌❌❌❌✅⚠️ частично❌
Защита от подмены схемы через ссылки на символы✅❌❌❌❌❌❌✅✅❌
Пределы разбора против отказа в обслуживании✅❌❌❌❌❌❌✅✅❌
Абзацы из пользовательского текста✅❌❌❌❌❌❌✅❌❌
Адреса в тексте становятся ссылками✅❌❌❌❌❌❌✅❌❌
Приведение адресов к абсолютным✅❌❌❌❌❌❌✅❌❌
Пометка внешних ссылок✅❌❌❌❌❌❌✅❌❌
Переносимость и сопровождение
Работа без расширений PHP, кроме json и mbstring✅✅✅❌❌❌✅✅❌✅
Сериализация дерева в JSON, XML, YAML и обратно✅❌❌❌❌❌❌❌❌❌
Чтение и запись файлов разметки✅❌❌✅✅❌❌❌❌✅
Единый фасад для всех операций✅⚠️ частично⚠️ частично❌❌❌❌⚠️ частично❌❌
Строгая типизация и уровень max статического анализа✅⚠️ частично✅❌⚠️ частично⚠️ частично⚠️ частично❌⚠️ частично❌
Документация на шести языках✅⚠️ частично❌❌❌⚠️ частично❌❌⚠️ частично❌
Всего🏆 6643911961794

🏆 Победитель: cloud-castle/html-builder — 66 / 66; ближайший: ezyang/htmlpurifier (17).

2. Покрытие возможностей

РешениеВозможностейДоляИтог
🏆 cloud-castle/html-builder66 / 66100%лучшее среди аналогов
ezyang/htmlpurifier17 / 6626%аналог
voku/simple_html_dom11 / 6617%аналог
masterminds/html59 / 6614%аналог
symfony/dom-crawler + css-selector9 / 6614%аналог
symfony/html-sanitizer9 / 6614%аналог
sabberworm/php-css-parser6 / 669%аналог
nette/utils (Html)4 / 666%аналог
matthiasmullie/minify4 / 666%аналог
yiisoft/html3 / 665%аналог

🏆 Победитель: cloud-castle/html-builder — 66 / 66; ближайший: ezyang/htmlpurifier (17).

3. Производительность

Одинаковая операция для всех аналогов, минимум из повторов, без Xdebug.

Построение документа объектной моделью (200 блоков)

РешениеПоказательИтог
nette/utils (Html)нет данныханалог
yiisoft/htmlнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Построение документа потоковой записью (200 блоков)

РешениеПоказательИтог
nette/utils (Html)нет данныханалог
yiisoft/htmlнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор документа 24 КБ в объектную модель

РешениеПоказательИтог
masterminds/html5нет данныханалог
voku/simple_html_domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор и выборка по селектору «ul.catalog > li.item > a»

РешениеПоказательИтог
symfony/dom-crawler + css-selectorнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор и выборка по записи XPath «//ul[…]/li[…]/a»

РешениеПоказательИтог
symfony/dom-crawler + ext-domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Выборка по селектору «ul.catalog > li.item > a» без построения дерева

РешениеПоказательИтог
symfony/dom-crawler + css-selectorнет данныханалог
voku/simple_html_domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор таблицы стилей из 200 правил

РешениеПоказательИтог
sabberworm/php-css-parserнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Очистка недоверенной разметки 21 КБ деревом

РешениеПоказательИтог
ezyang/htmlpurifierнет данныханалог
symfony/html-sanitizerнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Очистка недоверенной разметки 21 КБ потоком

РешениеПоказательИтог
ezyang/htmlpurifierнет данныханалог
symfony/html-sanitizerнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Сжатие кода JavaScript 14 КБ

РешениеПоказательИтог
matthiasmullie/minifyнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

4. Потребление памяти

Пиковая память процесса на тех же сценариях, изолированный запуск на каждый случай.

Построение документа объектной моделью (200 блоков)

РешениеПоказательИтог
nette/utils (Html)нет данныханалог
yiisoft/htmlнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Построение документа потоковой записью (200 блоков)

РешениеПоказательИтог
nette/utils (Html)нет данныханалог
yiisoft/htmlнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор документа 24 КБ в объектную модель

РешениеПоказательИтог
masterminds/html5нет данныханалог
voku/simple_html_domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор и выборка по селектору «ul.catalog > li.item > a»

РешениеПоказательИтог
symfony/dom-crawler + css-selectorнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор и выборка по записи XPath «//ul[…]/li[…]/a»

РешениеПоказательИтог
symfony/dom-crawler + ext-domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Выборка по селектору «ul.catalog > li.item > a» без построения дерева

РешениеПоказательИтог
symfony/dom-crawler + css-selectorнет данныханалог
voku/simple_html_domнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Разбор таблицы стилей из 200 правил

РешениеПоказательИтог
sabberworm/php-css-parserнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Очистка недоверенной разметки 21 КБ деревом

РешениеПоказательИтог
ezyang/htmlpurifierнет данныханалог
symfony/html-sanitizerнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Очистка недоверенной разметки 21 КБ потоком

РешениеПоказательИтог
ezyang/htmlpurifierнет данныханалог
symfony/html-sanitizerнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

Сжатие кода JavaScript 14 КБ

РешениеПоказательИтог
matthiasmullie/minifyнет данныханалог
cloud-castle/html-builderнет данныханалог

🏆 Победитель: нет данных.

5. Безопасность и корректность

Возможность🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Экранирование по контексту (текст, атрибут, CSS, JS, URL)✅⚠️ частично⚠️ частично⚠️ частично❌❌❌⚠️ частично⚠️ частично❌
Белый список схем адресов✅❌❌❌❌❌❌✅✅❌
Очистка разметки по белым спискам✅❌❌❌❌❌❌✅✅❌
Потоковая очистка без дерева✅❌❌❌❌❌❌❌❌❌
Отбор свойств инлайнового стиля при очистке✅❌❌❌❌❌❌✅❌❌
Запрет выражений CSS и адресов javascript: в стилях✅❌❌❌❌❌❌✅⚠️ частично❌
Защита от подмены схемы через ссылки на символы✅❌❌❌❌❌❌✅✅❌
Пределы разбора против отказа в обслуживании✅❌❌❌❌❌❌✅✅❌
Абзацы из пользовательского текста✅❌❌❌❌❌❌✅❌❌
Адреса в тексте становятся ссылками✅❌❌❌❌❌❌✅❌❌
Приведение адресов к абсолютным✅❌❌❌❌❌❌✅❌❌
Пометка внешних ссылок✅❌❌❌❌❌❌✅❌❌
Всего🏆 120000001040

🏆 Победитель: cloud-castle/html-builder — 12 / 12; ближайший: ezyang/htmlpurifier (10).

6. Стандарты безопасности

Стандарт безопасности🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Файл SECURITY.md с политикой раскрытия уязвимостей✅✅✅❌❌✅✅❌✅❌
Публикация рекомендаций по безопасности (security advisories)⚠️ частично✅✅✅❌✅✅✅✅✅
Проверка зависимостей composer audit в непрерывной сборке✅❌✅❌❌✅❌❌✅❌
Оценка OpenSSF Scorecard❌❌✅❌❌✅❌❌✅❌
Статический анализ безопасности (Psalm taint, PHPStan)✅⚠️ частично✅❌⚠️ частично⚠️ частично⚠️ частично❌⚠️ частично❌
Защита от CWE-79 (межсайтовое исполнение сценариев)✅⚠️ частично⚠️ частично❌❌❌❌✅✅❌
Защита от CWE-400 (исчерпание ресурсов при разборе)✅❌❌❌❌❌❌⚠️ частично⚠️ частично❌
Защита от CWE-601 (перенаправление на недоверенный адрес)✅❌❌❌❌❌❌✅✅❌
Защита от CWE-1333 (отказ через регулярные выражения)✅❌❌❌❌❌❌❌❌❌
Тесты на попытки обхода защиты (XSS-набор)✅❌❌❌❌❌❌✅✅❌
Мутационное тестирование кода безопасности (MSI 100%)✅❌❌❌❌❌❌❌❌❌
Подписанные теги релизов❌⚠️ частично✅❌❌✅❌❌✅❌
Всего🏆 9261052481

🏆 Победитель: cloud-castle/html-builder — 9 / 12; ближайший: symfony/html-sanitizer (8).

7. Качество кода

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Покрытие строк тестами100%95%100%92%87%96%93%75%97%90%
Индекс мутационного тестирования (MSI)100%нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Уровень PHPStan108100598090
Уровень Psalm (errorLevel, чем ниже — строже)1нет данных1нет данных4нет данныхнет данныхнет данныхнет данныхнет данных
Проверка стиля кода (PHPCS/PSR-12)✅✅✅❌✅✅✅❌✅❌
Контроль архитектурных слоёв (Deptrac)✅❌❌❌❌❌❌❌❌❌
Проверка мёртвого кода (PHPMD, Psalm unused)✅❌✅❌❌❌❌❌❌❌
Тесты производительности и утечек памяти в сборке✅❌❌❌❌❌❌❌❌❌
Русская документация с примерами на каждую возможность✅❌❌❌❌❌❌❌❌❌
Всего🏆 9150111010

🏆 Победитель: cloud-castle/html-builder — 9 / 9; ближайший: yiisoft/html (5).

8. Проверки по видам

Таблица на каждый вид проверки: синтаксис, Psalm, PHPStan, PHPMD, PHPCS, Rector, Deptrac, мутации, покрытие и утечки памяти.

Синтаксическая проверка (phplint)

Разбор каждого файла пакета на всех поддерживаемых версиях PHP.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Проверка синтаксиса в сборке✅✅✅✅✅✅✅❌✅✅
Версий PHP в матрице сборки5544444344
Всего🏆 2🏆 211111011

🏆 Победитель: cloud-castle/html-builder, nette/utils (Html) — 2 / 2; ближайший: yiisoft/html (1).

Статический анализ Psalm

Строгость уровня и поиск неиспользуемого кода.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Уровень Psalm (чем ниже — строже)1нет данных1нет данных4нет данныхнет данныхнет данныхнет данныхнет данных
Поиск неиспользуемого кода (findUnusedCode)✅❌❌❌❌❌❌❌❌❌
Всего🏆 2010000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: yiisoft/html (1).

Статический анализ PHPStan

Уровень строгости и число оставленных исключений в базовой линии.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Уровень PHPStan108100598090
Записей в базовой линии (игнорируемых ошибок)0нет данных0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 20🏆 20000000

🏆 Победитель: cloud-castle/html-builder, yiisoft/html — 2 / 2; ближайший: nette/utils (Html) (0).

Анализ сложности (PHPMD)

Чистота кода, неиспользуемые элементы и пороги сложности.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
PHPMD в сборке✅❌❌❌❌❌❌❌❌❌
Замечаний PHPMD0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2000000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: nette/utils (Html) (0).

Проверка стиля (PHPCS/PSR-12)

Единый стиль кода и отсутствие расхождений с PSR-12.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Проверка стиля в сборке✅✅✅❌✅✅✅❌✅❌
Замечаний стиля0нет данных0нет данныхнет данных0нет данныхнет данных0нет данных
Всего🏆 21🏆 201🏆 210🏆 20

🏆 Победитель: cloud-castle/html-builder, yiisoft/html, symfony/dom-crawler + css-selector, symfony/html-sanitizer — 2 / 2; ближайший: nette/utils (Html) (1).

Проверка модернизации (Rector)

Код соответствует возможностям целевой версии PHP без устаревших конструкций.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Rector в сборке✅❌✅❌✅❌❌❌❌❌
Предлагаемых правок0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2010100000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: yiisoft/html (1).

Контроль архитектурных слоёв (Deptrac)

Направление зависимостей между слоями проверяется автоматически.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Deptrac в сборке✅❌❌❌❌❌❌❌❌❌
Нарушений слоёв0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2000000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: nette/utils (Html) (0).

Мутационное тестирование

Мутанты, которых тесты не замечают, — мера настоящей полноты тестов.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Индекс мутационного тестирования (MSI)100%нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Выживших мутантов0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2000000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: nette/utils (Html) (0).

Тесты безопасности

Отдельный набор тестов на попытки обхода защиты и на устойчивость разбора.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Набор тестов на обход защиты в сборке✅❌❌❌❌❌❌✅✅❌
Тесты устойчивости к отказу через регулярные выражения✅❌❌❌❌❌❌❌❌❌
Всего🏆 2000000110

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: ezyang/htmlpurifier (1).

Покрытие тестами

Доля строк и классов, исполняемых тестами.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Покрытие строк100%95%100%92%87%96%93%75%97%90%
Покрытие классов100%нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2010000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: yiisoft/html (1).

Проверка утечек памяти

Рост памяти после повторного создания и уничтожения деревьев.

Показатель🏆 CloudCastlenetteyiisoftmastermindsvokucrawlersabberwormpurifiersanitizerminify
Проверка утечек в сборке✅❌❌❌❌❌❌❌❌❌
Рост памяти за 1000 циклов0нет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данныхнет данных
Всего🏆 2000000000

🏆 Победитель: cloud-castle/html-builder — 2 / 2; ближайший: nette/utils (Html) (0).

О памяти честно. Пакет строит объектную модель, поэтому на разборе документа в 24 КБ занимает около 6 МБ против 2 МБ у обёрток над ext-dom. В потоковых режимах — запись разметки, очистка, сжатие — расход падает до 2 МБ, и там пакет не уступает никому. Память — единственная ось, где он уступает при построении дерева; по функциональности, безопасности и качеству кода он лидирует.

Те же таблицы отдельными страницами: возможности, производительность и память, безопасность и стандарты, качество кода, проверки по видам.

Честно о плюсах и минусах

Плюсы

  • Полная объектная модель: элемент, атрибут, стиль, значение, событие и узел скрипта — объекты с проверками, а не строки.
  • Работает без расширений PHP, кроме json и mbstring: одинаково на любом хостинге.
  • Самая быстрая потоковая запись разметки (0.78 мс против 1.11 мс), разбор таблицы стилей (2.1 мс против 18.8 мс) и потоковая очистка недоверенной разметки (4.7 мс против 7.0 мс), которая ещё и расходует меньше всех памяти — 2 МБ против 4 МБ у обоих санитайзеров.
  • Выборка по дереву быстрее обёртки над libxml: 5.5 мс против 6.8 мс по селектору CSS и 5.5 мс против 6.9 мс по записи XPath на документе 24 КБ — и это на чистом PHP, без ext-dom.
  • Разбор документа быстрее masterminds/html5 (4.3 мс против 7.5 мс), хотя тот читает разметку расширением libxml.
  • Потоковая выборка находит совпадения без построения дерева: 4.0 мс против 6.7 мс у symfony/dom-crawler на документе 24 КБ, 2 МБ памяти вместо 6 МБ.
  • Безопасность заложена в типы: экранирование по контексту, охрана схем, пределы разбора.
  • Покрытие тестами 100%, мутационный индекс 100%, статический анализ максимального уровня.
  • Документация на шести языках и страница на каждую возможность.

Минусы

  • Пакет моложе и менее распространён, чем аналоги: у него нет истории в десятки лет и тысяч зависимых проектов.
  • Объектная модель тратит больше памяти, когда строит дерево: на документ в 24 КБ уходит около 6 МБ против 2 МБ у обёрток над ext-dom. Это осознанный обмен памяти на функциональность — в потоковых режимах расход падает до 2 МБ, и там пакет не уступает никому.
  • Очистка деревом чуть уступает symfony/html-sanitizer по времени (7.2 мс против 7.0 мс на 21 КБ), опережая при этом ezyang/htmlpurifier (8.1 мс); потоковая очистка того же содержимого быстрее обоих санитайзеров — 4.7 мс.
  • Чтение документа расширением libxml быстрее на сырой скорости: там работает код на C, и на чистом PHP это не отыгрывается. Поэтому разбор в дерево — 4.3 мс против 1.3 мс у voku/simple_html_dom, а потоковая выборка — 4.0 мс против его же 1.6 мс на 24 КБ.
  • Построение дерева объектной моделью медленнее строкового сборщика (3.4 мс против 1.1 мс на 200 блоков) — это плата за проверки и типы; потоковая запись той же разметки укладывается в 0.78 мс и обгоняет всех.
  • Сжатие JavaScript медленнее matthiasmullie/minify (1.95 мс против 0.84 мс на 14 КБ): наш минификатор разбирает код в лексемы и учитывает автоматическую расстановку точек с запятой, а не заменяет по регулярным выражениям — за счёт этого он не ломает код, где перевод строки завершает инструкцию.

Когда пакет подходит

  • Генерация разметки в CRM и админках. Формы, таблицы, карточки собираются кодом, а не шаблонами: типизированные методы не дают выпустить неверный атрибут.
  • Очистка пользовательского содержимого. Письма, комментарии, описания товаров: политика очистки описывается белыми списками, а потоковый режим держит память под контролем.
  • Письма и выгрузки. Инлайновые стили, XML-карты, выгрузки на сотни мегабайт — потоковый писатель пишет разметку частями.
  • Обработка чужих страниц. Разбор, выборка по селекторам, правка и повторный вывод без расширений PHP — удобно для парсеров и импортёров.
  • Проекты с требованиями к безопасности. Финтех и медицина: экранирование по контексту, охрана схем адресов и пределы разбора снижают риск внедрения кода.

Когда пакет не нужен: разовая склейка двух строк разметки (хватит sprintf) или задача «прочитать текст большого документа как можно быстрее» — там выгоднее обёртка над ext-dom.

Разработка

composer ci

Команда выполняет всё, что проверяет сборка: линтеры, статический анализ, тесты, покрытие, проверку документации и примеров.

Полный прогон в порядке «синтаксис → Psalm → PHPStan → PHPMD → PHPCS → Rector → Deptrac → тесты → покрытие → мутации → безопасность → память → утечки → производительность → документация»:

composer test:all

Полный список команд — composer list; описание каждой — в composer.json (раздел scripts-descriptions).

Документация

Лицензия

MIT. Подробности — в файле LICENSE.

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano