SuperAPI AI 工具集

openui-forge-php

前端与建站

查看项目

更新于 10-16 07:45

技能介绍

OpenUI Forge — PHP 是一套用 React 前端加 Laravel 后端构建生成式 UI 应用的方案。它的核心特点是把 OpenAI API 的原生 SSE 响应通过 response()->stream() 直接透传,不做重新封装。

【用途】 用于搭建生成式 UI(generative UI)应用:前端负责渲染,Laravel 后端负责调用 OpenAI 并把流式响应转发给浏览器。激活触发词包括 "openui php"、"openui laravel"、"openui php backend"、"generative ui php"、"laravel streaming ui backend"。

【前置条件】 前端:Node.js >= 22(推荐 24 LTS)、React >= 18.3.1(推荐 19+)。 后端:PHP >= 8.3、Laravel 13.x(Laravel 13 最低要求 PHP 8.3,支持 8.3 至 8.5)、Composer。guzzlehttp/guzzle 随 Laravel 一起提供,支撑 Http facade,调用 OpenAI 无需额外依赖。 环境变量:需设置 OPENAI_API_KEY。

【快速开始】

  1. 创建 React 前端并安装 OpenUI 依赖:npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod
  2. 生成系统提示词:npx @openuidev/cli generate ./src/lib/library.ts --out backend/storage/app/system-prompt.txt
  3. 创建 Laravel 后端(见完整代码)。全新应用需先执行一次 php artisan install:api 启用 API 路由。
  4. 运行:后端 php artisan serve 监听 :8000,前端监听 :3000。

【后端实现要点】 composer.json 的 require 块声明 php ^8.3 与 laravel/framework ^13.0。 routes/api.php 中注册 POST /chat 路由指向 ChatController@chat(install:api 会创建该文件并加 /api 前缀,因此实际地址为 POST /api/chat)。 ChatController 中:系统提示词按 worker 进程加载一次并复用;控制器内必须用 config() 而非 env() 读取配置,因为执行 php artisan config:cache 后(生产环境标准做法)env() 在配置文件之外会返回 null。请求校验 messages 数组,强制在开头插入服务端系统提示词,不信任客户端传来的 system 消息。调用 OpenAI 时使用 Http::withToken()->withOptions(['stream' => true]),stream => true 返回仍在线路上的 Guzzle PSR-7 响应,从而逐块读取而非整体缓冲。上游失败时用 abort() 抛出状态码与错误体。最后用 response()->stream() 逐块读取 8192 字节并 echo + flush(),设置 Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive、X-Accel-Buffering: no。 config/services.php 增加 openai 条目,通过 env() 读取 OPENAI_API_KEY、OPENAI_BASE_URL(默认 https://api.openai.com/v1)、OPENAI_MODEL(默认 gpt-5.5)。 config/cors.php 用 php artisan config:publish cors 发布,paths 为 api/*,allowed_methods 为 POST、OPTIONS,allowed_origins 固定为前端源(不要用通配符),allowed_headers 为 Content-Type、Authorization,supports_credentials 保持 false。Laravel 内置 HandleCors 中间件会自动处理 OPTIONS 预检。

【前端实现要点】 app/chat/page.tsx 使用 @openuidev/react-ui 的 FullScreen 组件,传入 componentLibrary={openuiChatLibrary}、streamProtocol={openAIAdapter()}、messageFormat={openAIMessageFormat},apiUrl 指向 http://localhost:8000/api/chat。 注意:openAIReadableStreamAdapter() 用于 NDJSON(无 data: 前缀),在此场景会静默无输出。不要使用 Laravel 的 response()->eventStream(),它会把每个 yield 包装成命名 SSE 事件并追加 </stream> 哨兵,改写字节从而破坏 openAIAdapter()。

【系统提示词生成】 npx @openuidev/cli generate ./src/lib/library.ts --out backend/storage/app/system-prompt.txt

【验证清单】 storage/app/system-prompt.txt 存在;.env 中设置 OPENAI_API_KEY(如需覆盖则含 OPENAI_BASE_URL / OPENAI_MODEL);已运行 php artisan install:api 使 POST /api/chat 存在;config/cors.php 的 allowed_origins 列出前端源而非 *;响应直接从 OpenAI API 透传 SSE;设置 X-Accel-Buffering: no 防止 nginx/FastCGI 缓冲;前端 apiUrl 指向 http://localhost:8000/api/chat;前端使用 openAIAdapter() 与 openAIMessageFormat;FullScreen 传入 componentLibrary={openuiChatLibrary};根布局导入 CSS(@openuidev/react-ui/components.css)。

【常见错误】 CORS 被拦截:源不匹配,在 config/cors.php 设置前端源。 /api/chat 返回 404:API 路由未安装,运行 php artisan install:api 并确认 routes/api.php 存在。 system-prompt.txt not found:文件缺失,运行 CLI 生成命令输出到 storage/app/system-prompt.txt。 500 OPENAI_API_KEY not set:环境变量缺失,或在 config:cache 后用 env() 读取;应在 .env 设置并通过 config('services.openai.key') 读取(缓存安全)。 上游错误经 abort() 抛出:OpenAI 密钥无效或模型错误,检查 OPENAI_API_KEY、OPENAI_MODEL、OPENAI_BASE_URL。 响应一次性到达(无流式):输出被服务器缓冲,保持 X-Accel-Buffering: no,确保 flush() 执行且无整页输出缓冲包裹。 空响应:适配器错误,使用 openAIAdapter()(SSE)而非 openAIReadableStreamAdapter()(NDJSON)。

【替代方案】 存在官方风格的 OpenAI PHP 客户端 openai-php/client(要求 PHP 8.2+),提供 createStreamed() 辅助方法作为直接调用 HTTP 端点的替代。本方案默认保留 Laravel 自带的 Guzzle Http facade 作为无额外依赖的默认选择。纯 ext-curl + CURLOPT_WRITEFUNCTION 变体(在回调中返回块的字节数,并在其中 echo+flush())见 templates/handler-php.php.template。