承接 syntaxx/phpx-framework 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

syntaxx/phpx-framework

Composer 安装命令:

composer require syntaxx/phpx-framework

包简介

PHPX Framework - A modern PHP framework with JSX-like syntax support

README 文档

README

React-style components, written in PHP. A small, isomorphic UI runtime: the same component renders on the server (SSR) and runs in the browser as PHP compiled to WebAssembly, then hydrates to interactive — keeping input focus and caret across re-renders.

Status: Technology Preview. The core (reconciler, hooks, SSR + hydration, Suspense, router) is solid and tested, but APIs may change and the edges are sharp. Not production-ready yet.

function Counter($props) {
    [$count, $setCount] = useState(0);
    return (
        <div className="text-center">
            <h1>Count: {$count}</h1>
            <button onClick={fn() => $setCount($count + 1)}>+</button>
        </div>
    );
}

The same Counter is server-rendered to HTML and then hydrated in the browser — no separate JavaScript implementation, no hydration-mismatch class of bugs.

What it is (and isn't)

  • A persistent-instance virtual-DOM reconciler (Preact-class): keyed diffing, surgical DOM patching, focus/caret preservation. It is not React Fiber — rendering is synchronous; there is no scheduler, no time-slicing, no concurrent mode.
  • Isomorphic by construction: one tree renders through a pluggable host config to real DOM (browser), an HTML string (server), or an in-memory fake (tests). Server and client seed the same hydration state.
  • Pure PHP. The browser runtime is PHP-in-WASM via the VRZNO DOM bridge; on the server it's ordinary PHP.

Installation

composer require syntaxx/phpx-framework

Requires PHP 8.4+ (developed and tested on PHP 8.4). The hook functions are registered globally via Composer's files autoload, so they're available everywhere once the autoloader is loaded.

Writing JSX-in-PHP (<div>…</div>) requires the PHPX compiler, which transforms it into the plain Component::create(...) calls shown below. For a full project (compiler + WASM build + dev server) start from the PHPX starter kit rather than wiring this package up by hand.

Components

A component is a plain function that takes $props and returns an element tree.

function Greeting($props) {
    return <p>Hello, {$props['name']}!</p>;
}
  • Capitalized names are components (resolved from global functions); lowercase names are host elements (div, button, …).
  • Without the compiler, elements are created directly:
use Syntaxx\PHPX\Framework\Component;

Component::create('div', ['className' => 'card'], [
    Component::create('Greeting', ['name' => 'world'], []),
]);
  • Events use on* props with PHP callables: onClick, onInput, onKeyPress, … (onDoubleClickdblclick). Handlers are delegated — one root listener per event type — so they survive re-renders untouched.
<input value={$text} onInput={fn($e) => $setText($e->target->value)} />

Hooks

All hooks are global functions (no use needed):

Hook Signature Purpose
useState useState($initial, ?string $hydrationKey = null): [$value, $setValue] Local state; supports functional updates and === bail-out
useEffect useEffect(callable $fn, ?array $deps = null): void Side effects after commit (never runs on the server)
useRef useRef($initial = null): Ref Stable mutable container ($ref->current); auto-binds to the host node when passed as a ref prop
useMemo useMemo(callable $factory, array $deps): mixed Memoized value
useCallback useCallback(callable $cb, array $deps): callable Memoized callback
useData useData(string $key, callable $fetcher): [$data, $loading, $error] Isomorphic data: server fetches + seeds, client reads the seed (fetches once if unseeded)
useSuspenseData useSuspenseData(string $key, callable $fetcher): mixed Returns the value or throws a Suspension caught by the nearest <Suspense>

Standard rules of hooks apply: call them unconditionally and in the same order every render.

Server-side rendering + hydration

Render to HTML on the server:

use Syntaxx\PHPX\Framework\{Component, ServerRenderer};

$result = ServerRenderer::render(
    Component::create('App', [], []),
    [],                                   // explicit initial state (optional)
    ['pathname' => $path, 'search' => $search]
);

echo "<div id=\"root\">{$result['html']}</div>";
echo ServerRenderer::stateScript($result['state']);   // <script id="__phpx_state__">…</script>

Hydrate the same tree in the browser (PHP-in-WASM entry point):

use Syntaxx\PHPX\Framework\{Component, Runtime, Router};

$root = Runtime::hydrateRoot($document->getElementById('root'));
$render = fn() => $root->render(Component::create('App', [], []));
$render();
Router::start($render);   // client-side navigation re-renders without rebooting WASM

Streaming SSR

StreamRenderer::stream($component, $state, $location) yields shell, boundary, and close chunks so the shell (with <Suspense> fallbacks) flushes first and boundary content streams in as data settles.

Routing

A minimal History-API router:

  • Router::start(callable $onChange) — intercept internal link clicks + popstate.
  • Router::navigate(string $href) — programmatic navigation.
  • Router::current(): array['pathname' => …, 'search' => …].
  • Environment::location() / Environment::isServer() — read location isomorphically.

Routing is flat pathname matching today (no route params or nested routes yet).

Architecture

Component tree ─▶ Reconciler ─▶ HostConfig backend ─▶ output
                  (keyed diff,    ├─ VrznoBackend  → real DOM (browser)
                   surgical        ├─ SsrBackend    → HTML string (server)
                   patching)       └─ FakeDomBackend→ in-memory (tests)

The reconciler keeps persistent nodes across renders and applies only the minimal set of mutations, which is what preserves focus, caret, scroll, and media state. Hooks are bound to those persistent instances. The HostConfig interface lets you render to any target.

What's implemented

  • ✅ Components, props, children, fragments
  • ✅ Hooks: useState, useEffect, useRef, useMemo, useCallback, useData, useSuspenseData
  • ✅ Delegated events with a synthetic-event object
  • ✅ Keyed reconciliation + surgical DOM patching (focus-preserving)
  • <Suspense> and streaming SSR
  • ✅ SSR + hydration (isomorphic, state-seeded)
  • ✅ Client-side router
  • ⬜ Context API, useReducer
  • ⬜ Route params / nested routes / route data loaders
  • ⬜ Concurrent / interruptible rendering

Testing

composer install
vendor/bin/phpunit

Tests run headlessly against an in-memory FakeDomBackend (no browser needed) and cover the reconciler, hooks, hydration, SSR, and Suspense.

Where this fits

PHPX Framework is one module of the Syntaxx / PHPX ecosystem:

  • PHP-X-Parser — JSX grammar + AST for PHP
  • PHPX-Compiler — transforms JSX-in-PHP → plain PHP
  • PHPX-BuildTools — build/pack/export/serve for WebAssembly projects
  • PHPX-WasmRuntimeVrzno — the PHP-WASM browser runtime (VRZNO)
  • PHPX Framework — this package: the component runtime

License

MIT

syntaxx/phpx-framework 适用场景与选型建议

syntaxx/phpx-framework 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 59 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 10 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 syntaxx/phpx-framework 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 syntaxx/phpx-framework 我们能提供哪些服务?
定制开发 / 二次开发

基于 syntaxx/phpx-framework 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 59
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 22
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-26