kavalhub/form-generator
Composer 安装命令:
composer require kavalhub/form-generator
包简介
Easily create, validate, and display forms.
关键字:
README 文档
README
PHP-библиотека для программного создания HTML-форм, привязки данных из запроса, валидации и рендеринга с опциональным Bootstrap-декоратором.
Требования
- PHP ^8.2
- Composer
Установка
composer require kavalhub/form-generator
Laravel (опционально)
composer require kavalhub/form-generator-laravel
Быстрый старт
use Kavalhub\FormGenerator\Html\Form; use Kavalhub\FormGenerator\Html\InputSubmit; use Kavalhub\FormGenerator\Html\InputText; use Kavalhub\FormGenerator\Request\ElementRequest; use Kavalhub\FormGenerator\Validator\ElementValidator; use Kavalhub\FormGenerator\Validator\Interface\ElementValidatorInterface; $form = (new Form('contact')) ->addElement( (new InputText('email'))->setRequired()->setPlaceholder('Email') ) ->addElement( (new InputSubmit('send'))->setDefaultValue('Отправить') ); /** @var ElementValidatorInterface $validator */ $validator = new ElementValidator(new ElementRequest()); $submit = $form->getByName('send'); if ($validator->checkSubmit($submit) && $validator->handle($form)) { // данные валидны } echo $form->render();
Точки расширения
Библиотека построена на интерфейсах — реализации можно подменять:
| Интерфейс | Назначение | Реализации в пакете |
|---|---|---|
RequestInterface |
Источник данных формы | ElementRequest, ArrayRequest, PostOnlyRequest |
ElementValidatorInterface |
Валидация и bind | ElementValidator |
DecoratorInterface |
Рендеринг с темой | AbstractDecorator; Bootstrap — пакет form-generator-bootstrap |
AjaxRenderStrategyInterface |
HTML/CSS для AJAX-патчей | NullAjaxRenderStrategy; Bootstrap — в bootstrap-пакете |
ElementEventDispatcher |
События элементов (связанные select, фильтры) | ElementChangedEvent, слушатели в приложении |
Подробнее: docs/element-events.md, docs/custom-templates.md.
flowchart LR
App[Приложение] --> RequestInterface
App --> ElementValidatorInterface
App --> DecoratorInterface
App --> AjaxRenderStrategyInterface
RequestInterface --> ElementRequest
RequestInterface --> PostOnlyRequest
RequestInterface --> LaravelRequestAdapter
ElementValidatorInterface --> ElementValidator
ElementValidatorInterface --> LaravelElementValidator
DecoratorInterface --> AbstractDecorator
AjaxRenderStrategyInterface --> NullAjaxRenderStrategy
DecoratorInterface --> BootstrapPackage[form-generator-bootstrap]
AjaxRenderStrategyInterface --> BootstrapPackage
Loading
Request: GET, POST и свои адаптеры
ElementRequest — по умолчанию ($_REQUEST)
Читает GET + POST + cookies. Подходит для фильтров и форм, отправляемых GET-запросом (см. demo-проект kavalhub/form-demo, каталог src/).
Demo-приложение
Примеры использования (Kavalhub\Example\) вынесены в отдельный проект и не входят в autoload при composer require kavalhub/form-generator. В репозитории библиотеки каталог example/ доступен только через autoload-dev для PHPUnit.
$request = new ElementRequest();
PostOnlyRequest — только POST
use Kavalhub\FormGenerator\Request\PostOnlyRequest; $request = new PostOnlyRequest();
ArrayRequest — для тестов и API
use Kavalhub\FormGenerator\Request\ArrayRequest; $request = new ArrayRequest(['contact_email' => 'a@b.c']);
Свой адаптер
Реализуйте RequestInterface::get(string $name): ?array — метод возвращает массив значений для поля с данным именем (getFormName()).
Validator
Контракт ElementValidatorInterface:
checkSubmit(InputSubmit $submit): bool— была ли отправлена формаhandle(ElementInterface $element): bool— bind из request, required, callbacks, CSRFisValid(): ?bool— результат последней проверки
Внедряйте интерфейс, а не конкретный класс:
public function __construct(private readonly ElementValidatorInterface $validator) {}
Callback-валидаторы
$input->addCallbackValidator(function (InputText $el): bool { if (!str_contains($el->getValue(), '@')) { $el->addError(['Некорректный email']); return false; } return true; });
Laravel-интеграция
Пакет kavalhub/form-generator-laravel — гибридный валидатор:
- Core (
ElementValidator) — bind, required, callbacks, CSRF - Laravel (
illuminate/validation) — правилаrequired|emailи т.д.
use Illuminate\Validation\Factory; use Kavalhub\FormGenerator\Html\Form; use Kavalhub\FormGenerator\Html\InputText; use Kavalhub\FormGenerator\Laravel\LaravelElementValidator; use Kavalhub\FormGenerator\Laravel\LaravelRequestAdapter; $request = new LaravelRequestAdapter($illuminateRequest); $validator = new LaravelElementValidator($request, app(Factory::class)); $validator->setRules([ 'contact_email' => 'required|email', ]); $form = (new Form('contact'))->addElement((new InputText('email'))->setRequired()); if ($validator->handle($form)) { // OK }
Ошибки Laravel автоматически попадают в addError() элементов через ElementDataCollector.
Bootstrap-декоратор
Пакет kavalhub/form-generator-bootstrap (с 3.3 вынесен из core):
composer require kavalhub/form-generator-bootstrap
use Kavalhub\FormGenerator\Bootstrap\BootstrapDecorator; use Kavalhub\FormGenerator\Decorator\Interface\DecoratorInterface; /** @var DecoratorInterface $decorator */ $decorator = new BootstrapDecorator($form); echo $decorator->getHtml();
Кастомные шаблоны для дизайнеров: docs/custom-templates.md.
Blade-декоратор
Пакет kavalhub/form-generator-blade — те же Bootstrap-стили, шаблоны {ClassName}.php в каталоге resources/Blade/:
composer require kavalhub/form-generator-blade
use Kavalhub\FormGenerator\Blade\BladeDecorator; echo (new BladeDecorator($form)) ->setTemplate(__DIR__ . '/resources/form-templates') ->getHtml();
Для AJAX: BladeAjaxRenderStrategy. Demo поддерживает переключатель HTML / Bootstrap / Blade и per-element шаблон для фасета «Бренд».
CSRF-защита (opt-in)
$form = (new Form('secure')) ->enableCsrf() ->addElement(/* ... */);
AJAX (3.1+)
Библиотека не навязывает JS-фреймворк. Сервер возвращает JSON с ключом REPLACE — массив патчей DOM. Два режима:
| Режим | Метод | Ответ |
|---|---|---|
| field | ElementAjaxHandler::handleField() |
ID, CLASS, ERROR (через AjaxRenderStrategyInterface) |
| form/block | ElementAjaxHandler::handleForm() / handleBlock() |
ID, HTML (через стратегию, напр. BootstrapAjaxRenderStrategy) |
Поиск элемента по DOM-id: ElementDataCollector::findById() или $form->getById().
Короткое имя поля — getByName(); для AJAX используйте getId() / getFormName().
Разметка AJAX на форме и полях
На Form, InputText, InputSubmit и других элементах с HtmlAttributes доступны:
$form->setMethod('get') ->setAjax(true) ->setUrlState('replaceState'); // 'pushState' | false — не менять URL $input = (new InputText('name'))->setAjax();
В HTML: data-fg-ajax="true", опционально data-fg-url-state="replaceState".
setAjax() на форме — перехват submit и (в demo) change на полях фильтра; на поле — field mode (action = getId()).
В demo URL state и AJAX POST используют одни и те же ключи, что collectPageData() (getFormName() из DOM): например demoSettings_decoratorFieldset_decorator, fl_gc_cat[], page. Decorator читается только по полному ключу demoSettings_decoratorFieldset_decorator (или из session).
Endpoint (пример)
use Kavalhub\FormGenerator\Ajax\AjaxRequest; use Kavalhub\FormGenerator\Ajax\ElementAjaxHandler; use Kavalhub\FormGenerator\Bootstrap\BootstrapAjaxRenderStrategy; use Kavalhub\FormGenerator\Request\ElementRequest; use Kavalhub\FormGenerator\Validator\ElementValidator; header('Content-Type: application/json; charset=utf-8'); if (!AjaxRequest::isXmlHttpRequest()) { http_response_code(400); exit; } $validator = new ElementValidator(new ElementRequest()); $handler = new ElementAjaxHandler($validator, new BootstrapAjaxRenderStrategy()); $form = /* ваша форма */; if ($targetId = AjaxRequest::readTargetId()) { echo $handler->handleField($form, $targetId)->jsonEncode(); exit; } if ($validator->checkSubmit($submit) && $validator->handle($form)) { echo $handler->handleBlock($table)->setMessage('Сохранено')->jsonEncode(); }
Параметр action (или target_id) = getId() поля, как в demo.
Клиент (минимальный пример, не входит в пакет)
function collectPageData() { const body = new FormData(); document.querySelectorAll('form').forEach((form) => { new FormData(form).forEach((value, key) => body.append(key, value)); }); return body; } function applyUrlState(form) { const mode = form?.dataset?.fgUrlState; if (!mode) return; const params = new URLSearchParams(); collectPageData().forEach((value, key) => params.append(key, value)); const url = `${location.pathname}?${params}`; (mode === 'pushState' ? history.pushState : history.replaceState).call(history, null, '', url); } document.querySelector('[data-fg-ajax="true"]').addEventListener('input', function () { const fd = collectPageData(); fd.set('action', this.id); fd.set(this.name, this.value); fetch('/ajax.php', { method: 'POST', body: fd, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(r => r.json()) .then(data => { data.REPLACE.forEach(patch => { const el = document.getElementById(patch.ID); el.classList.remove('is-valid', 'is-invalid'); if (patch.CLASS) el.classList.add(patch.CLASS); el.parentElement.querySelectorAll('.invalid-feedback').forEach(n => n.remove()); if (patch.ERROR) el.insertAdjacentHTML('afterend', patch.ERROR); if (patch.HTML) document.getElementById(patch.ID).outerHTML = patch.HTML; }); applyUrlState(this.closest('form[data-fg-url-state]')); }); });
Живой пример с переключателем «классика / AJAX», синхронизацией URL (setUrlState) и восстановлением фильтра из GET — demo-проект kavalhub/form-demo: главная демонстрация на ?page=filter (фильтр товаров, чекбоксы/радио на лету), также ?page=facet (добавление фасета).
JSON API (3.2+)
Структурированный обмен без HTML-патчей: валидация и сабмит формы через JSON.
| Класс | Назначение |
|---|---|
Request\JsonElementRequest |
Источник данных из JSON / массива |
Api\FormApiHandler |
handleField() / handleForm() → FormApiResponse |
Api\FormJsonSchemaExporter |
JSON Schema полей формы (интроспекция дерева) |
Api\OpenApiDocumentBuilder |
Сборка OpenAPI 3.0 из списка форм |
use Kavalhub\FormGenerator\Api\FormApiHandler; use Kavalhub\FormGenerator\Request\JsonElementRequest; use Kavalhub\FormGenerator\Validator\ElementValidator; $request = JsonElementRequest::fromArray(['contact_email' => 'user@example.com']); $handler = new FormApiHandler(new ElementValidator($request)); $response = $handler->handleForm($form); echo $response->jsonEncode(); // {"valid":true,"fields":{...},"data":{...}}
OpenAPI и наполнение БД через JSON — demo: GET /api.php, POST /api.php, Swagger UI на /api-docs.html.
Сбор данных из дерева элементов
use Kavalhub\FormGenerator\Util\ElementDataCollector; $data = ElementDataCollector::collectByFormName($form); // ['contact_email' => 'user@example.com', ...]
Поддерживаемые элементы
| Класс | Описание |
|---|---|
Html\Form |
Контейнер <form> |
Html\Group |
Группа полей с префиксом имени |
Html\InputText, Html\InputPassword, Html\InputNumber |
Текстовые поля |
Html\InputCheckbox, Html\InputRadio |
Переключатели |
Html\Select, Html\Option |
Выпадающий список |
Html\Textarea |
Многострочный ввод |
Html\InputHidden, Html\InputSubmit, Html\Button |
Скрытые и кнопки |
Html\Label, Html\Nav, Html\Link |
Разметка |
Html\Table\Table, Html\Table\Tr, Html\Table\Td, Html\Table\Th |
Таблицы |
Миграция 2.x → 3.x
- Namespace виджетов:
Kavalhub\FormGenerator\Form\*→Kavalhub\FormGenerator\Html\* - Таблицы:
Kavalhub\FormGenerator\Table\*→Kavalhub\FormGenerator\Html\Table\* - Рендеринг элементов:
getHtml()→render()(декораторы по-прежнему используютgetHtml()) Element— доменная модель без HTML; HTML-трейты и виджеты вsrc/Html/HtmlEscaperперенесён вKavalhub\FormGenerator\Html\Util\HtmlEscaper- Базовые HTML-классы:
HtmlElement,HtmlElementWithValue,HtmlCompositeElement— содержатtag,ClassList,Path - Доменный
Elementне имеетtag,getTag(),addClass()— только дерево, значения и валидация
Безопасность
- Значения полей, placeholder, href и сообщения об ошибках экранируются через
Html\Util\HtmlEscaper. Label::setAllowHtml()— явное разрешение HTML в подписи.ElementRequestиспользует$_REQUEST— удобно для GET-фильтров; для POST-only используйтеPostOnlyRequest.- CSRF включается явно через
Form::enableCsrf().
Тесты
composer install
composer test
Лицензия
MIT
kavalhub/form-generator 适用场景与选型建议
kavalhub/form-generator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 24 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 03 月 29 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「form」 「Validation form」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 kavalhub/form-generator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 kavalhub/form-generator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 kavalhub/form-generator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Diese Contao 4 Erweiterung stellt Google reCAPTCHA V2 in Form eines neuen Formularfeldes im Formulargenerator bereit. This extension provides Google reCAPTCHA V2 in the form of a new form field in the form generator of Contao Open Source CMS.
A Laravel Filament Forms slug field.
Adds request-parameter validation to the SLIM 3.x PHP framework
A jQuery augmented PHP library for creating and validating HTML forms
A Laravel validator for delimiter-separated list of emails.
A CakePHP behavior to validate foreign keys
统计信息
- 总下载量: 24
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 4
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-03-29