当前位置:首页>php>PHP 终于拥有实时超能力了!

PHP 终于拥有实时超能力了!

  • 2026-09-10 22:44:37
PHP 终于拥有实时超能力了!

概述

PHP-VIA 将您的 PHP 转换为一个响应式、支持多用户的服务器。无需 JavaScript。无需构建步骤。无需 API 层。只需 PHP 和 OpenSwoole。

实时引擎,用于在 PHP 中使用 Swoole 构建响应式 Web 应用。基于 OpenSwoole 实现异步 PHP,Datastar(RC.8 版本)处理 SSE + DOM 变形,以及 Twig 进行模板渲染,从而实现完全无 JavaScript 的服务端响应式用户界面。

文档与实时示例:

https://via.zweiundeins.gmbh

为什么选择 php-via?

  • 无需编写任何 JavaScript — Datastar 负责客户端的响应性、SSE 连接和 DOM 变形
  • 使用 Twig 模板 — 熟悉且功能强大的服务端模板引擎
  • 零构建步骤 — 无需转译、打包、node_modules 或前端构建工具
  • 默认实时 — 每个页面自动建立持久 SSE 连接
  • 作用域状态管理 — 支持 TAB、ROUTE、SESSION、GLOBAL 以及自定义作用域,精确控制状态共享范围
  • 单一高效 SSE 流 — 结合 Brotli 压缩,传输开销极低

系统要求

  • PHP 8.4 或更高版本
  • OpenSwoole 扩展
  • Composer

安装

composer require mbolli/php-via

快速上手

<?phprequire'vendor/autoload.php';use Mbolli\PhpVia\Via;use Mbolli\PhpVia\Config;use Mbolli\PhpVia\Context;$config = new Config();$config->withTemplateDir(__DIR__ . '/templates');$app = new Via($config);$app->page('/', function(Context $c): void{    $count = $c->signal(0, 'count');    $step  = $c->signal(1, 'step');    $increment = $c->action(function()use($count, $step, $c): void{        $count->setValue($count->int() + $step->int());        $c->syncSignals();    }, 'increment');    $c->view('counter.html.twig', ['count'     => $count,'step'      => $step,'increment' => $increment,    ]);});$app->start();

对应的 counter.html.twig 模板:

<divid="counter"><p>计数: <spandata-text="${{ count.id }}">{{ count.int }}</span></p><label>步长: <inputtype="number"data-bind="{{ step.id }}"></label><buttondata-on-click="@post('{{ increment.url }}')">增加</button></div>

运行:

php app.php# 访问 → http://localhost:3000

信号(Signals)—— 服务端与客户端实时同步的响应式状态

$name = $c->signal('Alice', 'name');$name->string();          // 读取当前值$name->setValue('Bob');   // 修改 → 自动推送更新到浏览器

模板中使用:

<input data-bind="{{ name.id }}"><span data-text="${{ name.id }}">{{ name.string }}</span>

动作(Actions)—— 客户端事件触发的服务端函数

$save = $c->action(function()use($c): void{// 保存逻辑...    $c->sync();}, 'save');

模板:

<button data-on-click="@post('{{ save.url }}')">保存</button>

作用域(Scopes)—— 控制状态共享范围和广播目标

作用域
共享范围
典型场景
Scope::TAB
每个浏览器标签页独立(默认)
个人表单、用户设置
Scope::ROUTE
同一路由下的所有用户
共享看板、多人协作编辑
Scope::SESSION
同一会话的所有标签页
跨标签页共享购物车
Scope::GLOBAL
全局所有用户
系统通知、全局公告
自定义(如 "room:lobby")
指定作用域内的所有连接
聊天室、游戏房间

视图(Views)

支持 Twig 模板文件或内联字符串:

$c->view('dashboard.html.twig', ['user' => $user]);

路径参数(自动注入)

$app->page('/blog/{year}/{slug}', function(Context $c, string $year, string $slug): void{// $year 和 $slug 已自动注入});

组件(Components)

可重用、带独立状态的子上下文:

$a = $c->component($counterWidget, 'a');$b = $c->component($counterWidget, 'b');

生命周期钩子

$c->onDisconnect(fn() => /* 清理资源 */);$c->setInterval(fn() => $c->sync(), 2000);  // 每 2 秒同步一次$app->onClientConnect(fn(string $id) => /* ... */);

广播(Broadcasting)

$c->broadcast();                    // 广播到当前作用域$app->broadcast(Scope::GLOBAL);     // 广播给所有人$app->broadcast('room:lobby');      // 广播到自定义作用域

工作原理(简要流程)

  1. 浏览器请求页面 → 服务端渲染完整 HTML 并建立 SSE 流
  2. 用户交互(点击等) → Datastar 通过 POST 发送信号值 + 动作 ID
  3. 服务端执行动作 → 更新信号/状态
  4. 服务端通过 SSE 推送 HTML 补丁 + 信号更新
  5. Datastar 在客户端应用 DOM 变形 → UI 无刷新实时更新

实时示例(均可在线体验并查看源码)

访问 https://via.zweiundeins.gmbh/examples 下的所有 demo:

  • 计数器(TAB 作用域)
  • 问候语表单
  • 多人共享待办事项(ROUTE)
  • 独立组件演示
  • 路径参数
  • 实时股票行情(自定义作用域 + 定时器)
  • 多房间聊天室
  • 客户端连接监控仪表盘
  • 多人生命游戏(Game of Life)
  • 所有作用域混合演示
  • 服务端流式传输的 DOOM 游戏(通过 SSE)

开发环境搭建

git clone https://github.com/mbolli/php-via.gitcd php-via && composer installcd website && php app.php    # 启动网站和示例(端口 3000)vendor/bin/pest              # 运行测试(85 个测试用例,240+ 断言)composer phpstan             # 静态分析(级别 6)composer cs-fix              # 修复代码风格

部署建议

使用单一 OpenSwoole 进程 + 反向代理(如 Caddy)。参考仓库中的 deploy/ 目录,包含 systemd 服务文件和 Caddy 配置示例。

典型架构:

浏览器 → Caddy (负责 TLS + Brotli 压缩) → OpenSwoole :3000

最新文章

随机文章