最简GraphQL endpoint只需三步:安装webonyx/graphql-php、用GraphQL\Type\Schema显式构造schema、手动处理HTTP入口解析JSON并调用executeQuery()返回json_encode结果。

PHP 实现 GraphQL API 不需要框架魔改,用 webonyx/graphql-php 就够了——但直接照抄文档会卡在 schema 定义和 resolver 绑定上。
怎么写一个最简可用的 GraphQL endpoint(不依赖 Laravel/Symfony)
核心是三件事:安装库、定义 schema、挂到 HTTP 入口。别碰任何“GraphQL 服务器封装包”,那些反而多一层抽象陷阱。
- 用 Composer 安装:
composer require webonyx/graphql-php - schema 必须用
GraphQL\Type\Schema显式构造,不能靠注解或文件扫描自动合并 - HTTP 层自己处理:接收
POST /graphql的 JSON body,解析query和可选的variables字段,传给GraphQL\GraphQL::executeQuery() - 返回结果必须手动
json_encode(),且要保留errors数组(哪怕空),否则 Apollo Client 会报Response not successful
resolver 函数里怎么拿到当前请求的参数和上下文
resolver 不是普通回调函数,它接收四个固定位置参数:$root、$args、$context、$info。漏掉任意一个,$args 就会是空数组。
-
$args是 query 中user(id: "123")这类参数的键值对,类型由 schema 中GraphQL\Type\Definition\InputObjectType或标量决定 -
$context是你传给executeQuery()的第三个参数,通常塞$_SERVER、数据库连接、Auth 用户对象——它不会自动从 request 解析 - 常见错误:在 resolver 里直接读
$_GET或$_POST,其实应该在入口层解析好,塞进$context再透传
为什么 schema 编译后报 “Field 'xxx' expected to return 'yyy' but got NULL”
这是类型校验失败,不是 PHP 报错,发生在执行阶段。根本原因是 resolver 返回值与 schema 声明的 type 不匹配,比如字段声明为 !String(非空字符串),但 resolver 返回了 null 或 0(PHP 里 0 == false,但 GraphQL 不认为 0 是有效 String)。
立即学习“PHP免费学习笔记(深入)”;
- 检查所有
resolve函数是否严格返回声明类型:String 字段别返回NULL,Int 字段别返回"123"(字符串) - 用
GraphQL\Type\Definition\NonNull包裹类型时,resolver 绝对不能返回null,连return $user->name ?: '';都得写成return $user->name ?? '';(避免0被转成空字符串) - 嵌套对象字段(如
user { profile { avatar } })的 resolver 如果返回null,整个子树就崩,得提前判空或用NullableType
怎么加认证和权限控制(比如只让登录用户查 email)
GraphQL 没有路由中间件概念,权限必须在 resolver 内部做,或者统一在 $context 构建阶段拦截。
- 推荐方式:入口层解析 token,查出用户 ID,存入
$context['user_id'];每个需要鉴权的 resolver 开头加if (!$context['user_id']) throw new Error('Unauthorized'); - 不要在 schema 定义里动态删字段(比如根据角色生成不同 schema),这会导致缓存失效、调试困难
- 敏感字段(如
email)的 resolver 可以直接返回null,但记得 schema 里别声明为!String,否则报错而不是静默隐藏
真正卡住人的从来不是语法,而是 resolver 返回值类型和 context 传递时机——这两个点错一次,debug 时看到的错误信息完全不指向真实问题。



















