首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PHP 终于拥有实时超能力了!

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

作者头像
Tinywan
发布2026-07-01 15:18:22
发布2026-07-01 15:18:22
1080
举报
文章被收录于专栏:开源技术小栈开源技术小栈

概述

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

安装

代码语言:javascript
复制
composer require mbolli/php-via

快速上手

代码语言:javascript
复制
<?php
require'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 模板:

代码语言:javascript
复制
<div id="counter">
    <p>计数: <span data-text="${{ count.id }}">{{ count.int }}</span></p>
    <label>步长: <input type="number" data-bind="{{ step.id }}"></label>
    <button data-on-click="@post('{{ increment.url }}')">增加</button>
</div>

运行:

代码语言:javascript
复制
php app.php
# 访问 → http://localhost:3000

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

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

模板中使用:

代码语言:javascript
复制
<input data-bind="{{ name.id }}">
<span data-text="${{ name.id }}">{{ name.string }}</span>

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

代码语言:javascript
复制
$save = $c->action(function () use ($c): void {
    // 保存逻辑...
    $c->sync();
}, 'save');

模板:

代码语言:javascript
复制
<button data-on-click="@post('{{ save.url }}')">保存</button>

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

作用域

共享范围

典型场景

Scope::TAB

每个浏览器标签页独立(默认)

个人表单、用户设置

Scope::ROUTE

同一路由下的所有用户

共享看板、多人协作编辑

Scope::SESSION

同一会话的所有标签页

跨标签页共享购物车

Scope::GLOBAL

全局所有用户

系统通知、全局公告

自定义(如 "room:lobby")

指定作用域内的所有连接

聊天室、游戏房间

视图(Views)

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

代码语言:javascript
复制
$c->view('dashboard.html.twig', ['user' => $user]);

路径参数(自动注入)

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

组件(Components)

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

代码语言:javascript
复制
$a = $c->component($counterWidget, 'a');
$b = $c->component($counterWidget, 'b');

生命周期钩子

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

广播(Broadcasting)

代码语言:javascript
复制
$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)

开发环境搭建

代码语言:javascript
复制
git clone https://github.com/mbolli/php-via.git
cd php-via && composer install

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

部署建议

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

典型架构:

代码语言:javascript
复制
浏览器 → Caddy (负责 TLS + Brotli 压缩) → OpenSwoole :3000
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 为什么选择 php-via?
  • 系统要求
  • 安装
  • 快速上手
    • 信号(Signals)—— 服务端与客户端实时同步的响应式状态
    • 动作(Actions)—— 客户端事件触发的服务端函数
    • 作用域(Scopes)—— 控制状态共享范围和广播目标
    • 视图(Views)
    • 路径参数(自动注入)
    • 组件(Components)
    • 生命周期钩子
    • 广播(Broadcasting)
  • 工作原理(简要流程)
  • 实时示例(均可在线体验并查看源码)
  • 开发环境搭建
  • 部署建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档