Привет, коллеги!
Решил организовать небольшую рубрику с новостями по проекту Boson PHP. Вкратце о проекте, для тех, кто не в курсе.

Boson PHP — это платформа для создания кроссплатформенных настольных приложений, которая позволяет использовать веб-технологии (PHP, JavaScript, HTML, CSS) для создания native-приложений. Она сочетает в себе интерпретатор PHP и движок WebView, что позволяет собирать приложения в единый исполняемый файл для Windows, Linux и macOS. Для PHP-разработчиков, желающих выйти за рамки веба и создавать кроссплатформенные приложения с использованием знакомого стека технологий. Его ключевые преимущества — легкость, производительность и простота.

Хедлайнер проекта Кирилл Несмеянов, ну а коллектив разработчиков: Алексей Гагарин, Дмитрий Дерепко и я (Данил Щуцкий) помогаем ему.

20 августа состоялся второй стрим по Boson PHP. Расскажу вкратце, что там было интересного. За 4 месяца с момента предыдущего прямого эфира в проекте произошло много изменений:

Запуск нового лендинга bosonphp.com

Последний месяц команда работала над новым лендингом, который зарелизили в прямом эфире. Весь лендинг создан с использованием веб-компонентов (основа Boson). Верстая лендинг чуть не надорвался @krvvko, спасибо ему за работу!

Новая документация

  • Переход с JetBrains WriterSite на собственное решение — предыдущая система была не очень удобна для версионирования и переводов. Делали лендинг, решили заодно создать и движок документации

  • Версионирование документации — доступны версии 15, 16, 17 и master с возможностью переключения

  • Четкое разделение по разделам:

    • Application — общие вопросы приложения

    • Windows — управление окнами

    • WebView — веб-интерфейс и компоненты

    • Deployment — компиляция и сборка

Демонстрация веб-компонентов

Значительная часть стрима была посвящена детальной демонстрации веб-компонентов — главной особенности Boson, которые используют нативные возможности браузеров вместо виртуального DOM. Давайте разберемся на примерах, как это работает.

Создаем свой первый компонент

Все просто — регистрируем компонент и используем. Главное правило: в названии тега должен быть дефис!

class MyAwesomeButton {}

$app = new Boson\Application();

// Tag component name
$tag = 'my-button';

// Component class name
$component = MyAwesomeButton::class;

$app->webview->components->add('my-button', MyAwesomeButton::class);
$app->webview->html = '<my-button>Нажми меня!</my-button>';

Делаем шаблоны

Обычный HTML-шаблон

Хотите кастомный внешний вид? Легко!

class MyAwesomeButton implements HasTemplateInterface
{
    public function render(): string
    {
        return <<<HTML
            <button class="fancy-btn">? Крутая кнопка! ?</button>
        HTML;
    }
}

Shadow DOM — для продвинутых

Shadow DOM изолирует ваши стили и добавляет поддержку слотов:

class MyCard implements HasShadowDomInterface
{
    public function render(): string
    {
        return <<<HTML
            <div class="card">
                <h3>Заголовок карточки</h3>
                <slot></slot> <!-- Сюда попадет содержимое -->
            </div>
        HTML;
    }
}

Следим за жизненным циклом

Хотите знать, когда ваш компонент появился или исчез со страницы?

class MyComponent implements HasLifecycleCallbacksInterface
{
    public function onConnect(): void
    {
        echo "Привет! Я появился на странице! ?";
    }

    public function onDisconnect(): void
    {
        echo "Пока! Меня удалили ?";
    }
}

Добавляем интерактивность

Свойства — данные из JavaScript

Отслеживаем, когда JS меняет свойства компонента:

class Counter implements HasPropertiesInterface
{
    public function onPropertyChanged(string $property, mixed $value): void
    {
        if ($property === 'count') {
            echo "Счетчик изменился! Новое значение: $value";
        }
    }

    public static function getPropertyNames(): array
    {
        return ['count']; // Следим за свойством count
    }
}
// В JavaScript
let counter = document.createElement('my-counter');
counter.count = 42; // PHP получит уведомление!

Методы — вызываем PHP из JavaScript

Самое интересное! Можно вызывать PHP-методы прямо из браузера:

class Calculator implements HasMethodsInterface
{
    public function onMethodCalled(string $method, array $args = []): mixed
    {
        switch ($method) {
            case 'add':
                return $args[0] + $args[1];
            case 'greet':
                return "Привет из PHP! ?";
            default:
                throw new \BadMethodCallException("Метод $method не найден");
        }
    }

    public static function getMethodNames(): array
    {
        return ['add', 'greet'];
    }
}
<!-- В HTML -->
<my-calculator onclick="this.greet()">Калькулятор</my-calculator>
// Или асинхронно из JS
const calc = document.createElement('my-calculator');
let result = await calc.add(5, 3); // Вернет 8!

Атрибуты — реагируем на изменения HTML

Следим за изменениями атрибутов в реальном времени:

class StatusBadge implements HasAttributesInterface
{
    public function onAttributeChanged(string $attribute, ?string $value, ?string $previous): void
    {
        if ($attribute === 'status') {
            if ($value === null) {
                echo "Статус удален!";
            } elseif ($previous === null) {
                echo "Добавлен статус: $value";
            } else {
                echo "Статус изменен с '$previous' на '$value'";
            }
        }
    }

    public static function getAttributeNames(): array
    {
        return ['status', 'priority'];
    }
}

События — обрабатываем клики и прочее

Ловим события браузера в PHP:

class InteractiveWidget implements HasEventListenersInterface
{
    public function onEventFired(string $event, array $args = []): void
    {
        if ($event === 'click') {
            $x = $args['x'];
            $y = $args['y'];
            echo "Кликнули по координатам: $x, $y";
        }
    }

    public static function getEventListeners(): array
    {
        return [
            'click' => [
                'x' => 'clientX',  // Переименовываем clientX в x
                'y' => 'clientY',   // Переименовываем clientY в y
            ],
        ];
    }
}

Реактивный контекст — управляем компонентом

Это ваш главный инструмент для программного управления компонентом:

use Boson\WebView\Api\WebComponents\ReactiveContext;

class SmartComponent implements HasMethodsInterface
{
    public function __construct(private ReactiveContext $ctx) {}

    public function refresh(): void
    {
        // Проверяем атрибуты
        if (! $this->ctx->attributes->has('loaded')) {
            $this->ctx->attributes->set('loaded', 'true');
        }

        // Меняем содержимое
        if ($this->ctx->content->html === '') {
            $this->ctx->content->html = '<p>Контент загружен! ✅</p>';
        }
    }

    public function onMethodCalled(string $method, array $args = []): mixed
    {
        if ($method === 'refresh') {
            $this->refresh();

            return 'Обновлено!';
        }
        
        return '';
    }

    public static function getMethodNames(): array
    {
        return ['refresh'];
    }
}

В документации можно изучить подробнее.

И помните: с Boson Web Components вы получаете всю мощь серверного PHP прямо в браузерных компонентах!

Демонстрация реального приложения: HappyWife HappyLife

Алексей Гагарин на стриме продемонстрировал своё приложение — систему с LLM-агентами для "спасения жизни мужиков", как он это назвал.

Изначальная архитектура: “обычное Spiral-приложение” на Roadrunner и FPM со стандартным веб-интерфейсом. Для создания приложения на Boson PHP потребовалось добавить только один файл — Boson bootloader из spiral-bridge пакета. Никаких изменений в коде — приложение заработало сразу.

В ходе тестирования приложения поняли, что для полного счастья не хватает:

  • WebSockets/Server-Sent Events — для real-time взаимодействия

  • Унифицированное API — одинаковый интерфейс для PHPS, Roadrunner и Boson

  • Стримовые ответы — для потокового вывода токенов от LLM

Технические детали архитектуры

Реактивность под капотом: как это работает изнутри

Кирилл подробно объяснил архитектуру системы и её особенности:

  • Единый процесс - PHP и WebView работают в одном процессе, общение между ними через shared memory без дополнительных накладных расходов.

  • API интеграция. Используется WebKit API и Blink API верхнего уровня. Вызовы проходят напрямую (в обход промежуточных слоев), а события DOM передаются напрямую в PHP-коллбеки.

  • Производительность. Позволяет выполнять ~100 тысяч операций в секунду, но есть узкое место — JSON encode/decode для сложных объектов

Операционные системы

Windows. Самая любимая у Boson PHP по состоянию на сегодняшний день:

  • Использует Edge WebView2 — самый стабильный движок

  • Сборка работает "из коробки" без дополнительных настроек

  • Есть проблема — готовый .exe имеет логотип PHP и метаданные от оригинального интерпретатора! Но есть план как победить это - требует патчинг COFF-файлов для замены иконки и версионной информации.

Linux. Работает, но с нюансами.

  • Проблемы с системами безопасности (AppArmor)

  • Не все дистрибутивы одинаково поддерживают WebKitGTK. Продумываются обходные пути: запуск в контейнере или отключение ограничений

macOS. Замыкает тройку лидеров.

  • Safari "не лучший браузер во вселенной" для таких задач

  • Полная поломка с Revolt — event loop не работает в принципе "На macOS даже простые вещи не работают. Revolt нарушает традиционные ценности macOS, его любовь к простоте и удобству" Отставание этой платфомы объясняется отсутствием у Кирилла устройства Mac для разработки (уже пофикшено и Кирилл купил себе для работы по Boson PHP).

Расширенная интеграция с PHP фреймворками

Уже реализованы:

  • Laravel: полноценный service provider

  • Symfony: готовый bundle

  • Spiral: встроенная интеграция

  • PSR-совместимые: через HTTP-мост

Размер и производительность: конкретные цифры

Сравнили Boson PHP и Native PHP. Как вы догадались Boson в руках своего автора не оставил шансов конкуренту - в разы легче и быстрее, как и написано на лендинге. Но всё равно есть куда стремиться и уже намечены еще варианты по дальнейшей оптимизации.

Ссылка на стрим:

Будущее проекта: планы и ожидания

Архитектурные улучшения

  • Система плагинов — вынос Network API, Battery API в отдельные расширения

  • Избежание конфликтов — не использовать существующие DI-контейнеры

  • Модульность — возможность включать в сборку только нужные компоненты

Ожидание релиза Saucer v7, обновления библиотеки для отображения WebView внутри нативных приложений. В нём ожидается:

  • Решение проблем с памятью — исправление багов PHP FFI с указателями

  • Нативные хендлы — прямой доступ к платформенным API

  • Новые возможности — камера, геолокация, нотификации через OS API

Boson PHP развивается! Приглашаю участвовать в разработке и тестировании. Присоединяйтесь!

Комментарии (18)


  1. dyadyaSerezha
    07.09.2025 13:13

    Не очень понял, какие это приложения? Сначала говорится о стандартных (самостоятельных) exe-файлах, а потом неоднократно упоминается некий браузер. Так для работы нужен браузер или как?

    Есть сравнения с аналогами на других языках? С++/Qt, C#/WPF/... , Java/JavaFx/... , JavaScript/"что-то, на чем написан UI для Visual Studio Code"?


    1. SerafimArts
      07.09.2025 13:13

      WebView - часть ядра любой современной ОС. Так что браузер не нужен.

      А перечисленные ниже технологии - это не аналоги. Из похожего только Tauri на Rust и с некоторой натяжкой Electron на JS. Возможно ещё есть что-то, например Saucer под C/C++, но они не столь популярные


      1. dyadyaSerezha
        07.09.2025 13:13

        Так что браузер не нужен.

        Тогда что за браузер имеется ввиду, например, тут:

        Можно вызывать PHP-методы прямо из браузера

        Почему не аналоги? Есть цель - создать десктопное приложение, желательно, сразу на нескольких платформах. Или что тут не так?


        1. opusmode
          07.09.2025 13:13

          1. WebView, по сути, это и есть браузер. Точнее его часть, сам рендеринг на основе системного. Вот пример на мобильном - вы нажали ссылочку в мессенджере, а она тут же открылась. Но открылся не полноценный браузер, со всем, а только web view

          2. Не аналоги они потому, что Electron это всё же JS, т.е. клиентская часть и бекенд в одном, плюс свой браузер, а PHP это всё же логика, т.е. бекенд. А фронтом там опять же будет JS. Таури это тот же JS\TS , а на Rust там по сути cli и bundler.

            Т.е. там приложением будет являтся бинарник с JS рантаймом, который либо тащит браузер, либо пользует web view,

            А тут GUI вообще не предусмотрен. Тут предусмотрено стандортное клиент-серверное взаимодействие, просто с возможностью быстро это дело связать с рантаймом и запихнуть в бинарный пакет


          1. dyadyaSerezha
            07.09.2025 13:13

            WebView, по сути, это и есть браузер.

            Нет, это очень умный и много чего умеющий, но модуль или контрол (UI-control). Вы же не философам пишете. Тщательнее.

            А тут GUI вообще не предусмотрен.

            Как так? Сколько же противоречий. Любое десктопное приложение, это GUI или консоль. Про консоль речи нет, значит, остается GUI. Ваш пользователь будет видеть что-то на экране, кроме простой консоли? Будет. Значит, это GUI-приложение.

            Тут предусмотрено стандортное клиент-серверное взаимодействие

            Как устроено приложение внутри, дело двадцатое. Важно, что пользователь получает автономное приложение на компе. Поэтому все приведенных мной примеры, это полные аналоги. - они решают абсолютно ту же задачу - создать автономное GUI-приложение на компе. Блин, сколько же тени на плетень вы навели на ровном месте.)


            1. opusmode
              07.09.2025 13:13

              1. Какой-то нелепый от вас загон. Вы выше не знаете, что есть WebView, а тут уже меня поучаете. Вообще-то WebView вполне себе называется Embed Browser . Просто потому, что в современных ОС это и есть урезанная версия системного браузера, которая должна вызвать рендеринг

              2. Тут нет противоречий вообще. Вам прямым текстом на странице документации пишется
                Boson isn’t a GUI framework. We’re not here to dictate how your app should look or feel. Use whatever front-end stack fits your workflow best — React, Angular, Vue, Svelte, jQuery, or just classic HTML and CSS. Prefer Bootstrap, Bulma or Tailwind? Go for it. Your UI, your rule

                Это значит, что Electron это полноценный фреймворк, который обеспечивает и отрисовку и взаимодействие с ОС в рамках себя. Тут же только прослойка взаимодействия, а UI фреймворк вы можете выбирать какой угодно.

              3. Вообще-то как устоено приложение внутри, это не двадцатое дело, а первое. И нет, это не аналоги. Я описал почему. Аналогами являются tauri и electron, пусть и с разными подходами.

              Я ничего не наводил, я очень чётко и ясно вам описал разницу, но моё описание было отфильтровано уровнем вашего понимания технологий, вот и всё.


              1. dyadyaSerezha
                07.09.2025 13:13

                Браузер, это самостоятельное, десктопное в данном случае, приложение. Определение у него такое. Следовательно, WebView, это не браузер.

                Далее, если статья вызывает кучу вопросов и для их разрешения надо идти и читать документацию на то, что и описывается в статье, то это говорит об уровне понимания автора, а не читающих. (зря вы про уровень понимания начали, нехорошо).

                Далее, например питоновский Dash тоже использует чужой React.js для фронта/GUI, но он перехватывает все вызовы и вообще скрывает наличие этого фреймворка от программиста, и весь UI определяется кодом на Питоне, поэтому из того, что Boson что-то там использует (не читая его документации) ещё ничего не следует.


  1. Mr_Cheater
    07.09.2025 13:13

    Я тоже не совсем понял. Так-то звучит интересно, но не очередной ли это Electron, только с поддержкой php?


    1. Hakhagmon
      07.09.2025 13:13

      это скорее "смотрите мы тоже можем laravel приложение скомпилировать".
      когда-то был jphp -> пишешь на php на выходе приложение на java.

      сейчас их главная проблема, что размер приложение 500мб+


  1. Vadiok
    07.09.2025 13:13

    Интересно узнать, сколько примерно занимает HelloWorld на нем на разных OS?


    1. SerafimArts
      07.09.2025 13:13

      Ну на Windows от 7-8 мегабайт. А дальше зависит от количества расширений, вплоть до 20+ и больше.


      1. Vadiok
        07.09.2025 13:13

        Спасибо. В целом очень неплохо, принимая во внимание, сколько бы занимало было на Electron.


  1. starfair
    07.09.2025 13:13

    Интересное решение! Я правильно полагаю, лицензия MIT? У меня пара вопросов, так как весьма любопытное решение, вполне может как раз, то что мне нужно будет для своего проекта:
    1. Есть ли у вас в планах некоего репозитория с готовыми примерами?
    2. Документация и сайт останется только на английском? Не то чтобы сильно напрягало, но читать проще все таки на родном.


  1. Dm4k
    07.09.2025 13:13

    А есть ли в планах заопенсорсить движок документации?


    1. SerafimArts
      07.09.2025 13:13

      Он и так на гитхабе в открытом виде https://github.com/boson-php/bosonphp.com


  1. WebMonet
    07.09.2025 13:13

    Как реагируют антивирусы? Помню, что это была одна из проблем всех подобных решений.


    1. SerafimArts
      07.09.2025 13:13

      Так же как на любой php бинарь.


      1. SerafimArts
        07.09.2025 13:13

        P.S. *Имеется ввиду php.exe или php (Linux, macOS, BSD), т.к. процесс компиляции под десктоп - конкатенация рантайма с phar (php энтрипоинт просто использует суффикс своего исполняемого файла в качестве исходников на выполнение VM).