本文目录导读:

在 PHP 中提供 GraphQL 接口,主要有以下几种方式:
使用 Webonyx GraphQL(最流行)
安装
composer require webonyx/graphql-php
基础实现示例
<?php
require_once 'vendor/autoload.php';
use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
// 1. 定义类型
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'hello' => [
'type' => Type::string(),
'resolve' => function() {
return 'Hello World!';
}
],
'user' => [
'type' => $userType,
'args' => [
'id' => Type::nonNull(Type::int())
],
'resolve' => function($root, $args) {
return getUserById($args['id']);
}
]
]
]);
$userType = new ObjectType([
'name' => 'User',
'fields' => [
'id' => Type::nonNull(Type::int()),
'name' => Type::string(),
'email' => Type::string()
]
]);
// 2. 创建 Schema
$schema = new Schema([
'query' => $queryType,
'mutation' => $mutationType // 可选
]);
// 3. 处理请求
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'];
$variables = isset($input['variables']) ? $input['variables'] : null;
try {
$result = GraphQL::executeQuery(
$schema,
$query,
null,
null,
$variables
);
$output = $result->toArray();
} catch (\Exception $e) {
$output = [
'errors' => [
['message' => $e->getMessage()]
]
];
}
header('Content-Type: application/json');
echo json_encode($output);
使用 Laravel + Lighthouse
安装
composer require nuwave/lighthouse php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider"
定义 Schema (graphql/schema.graphql)
type Query {
users: [User!]!
user(id: ID! @eq): User @find
}
type Mutation {
createUser(name: String!, email: String!): User! @create
updateUser(id: ID!, name: String): User! @update
}
type User {
id: ID!
name: String!
email: String!
posts: [Post!]! @hasMany
}
配置路由
// routes/api.php
Route::middleware('api')->group(function () {
Route::post('/graphql', function () {
return app('graphql')->executeQuery();
});
});
完整示例:PHP 原生实现
创建入口文件 graphql.php
<?php
header('Content-Type: application/json');
require_once 'vendor/autoload.php';
use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
// 模拟数据层
class Database {
private static $users = [
1 => ['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
2 => ['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com'],
];
private static $posts = [
1 => ['id' => 1, 'title' => 'Post 1', 'userId' => 1],
2 => ['id' => 2, 'title' => 'Post 2', 'userId' => 1],
3 => ['id' => 3, 'title' => 'Post 3', 'userId' => 2],
];
public static function getUser($id) {
return isset(self::$users[$id]) ? self::$users[$id] : null;
}
public static function getPosts($userId) {
return array_values(array_filter(self::$posts, function($post) use ($userId) {
return $post['userId'] == $userId;
}));
}
}
// 定义类型
$postType = new ObjectType([
'name' => 'Post',
'fields' => [
'id' => Type::nonNull(Type::int()),
'title' => Type::string(),
]
]);
$userType = new ObjectType([
'name' => 'User',
'fields' => [
'id' => Type::nonNull(Type::int()),
'name' => Type::string(),
'email' => Type::string(),
'posts' => [
'type' => Type::listOf($postType),
'resolve' => function($user) {
return Database::getPosts($user['id']);
}
]
]
]);
// 查询类型
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'user' => [
'type' => $userType,
'args' => [
'id' => Type::nonNull(Type::int())
],
'resolve' => function($root, $args) {
return Database::getUser($args['id']);
}
],
'hello' => [
'type' => Type::string(),
'resolve' => function() {
return 'Hello GraphQL!';
}
]
]
]);
// 创建 Schema
$schema = new Schema([
'query' => $queryType
]);
// 处理请求
try {
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
if (!$input || !isset($input['query'])) {
throw new Exception('Invalid GraphQL query');
}
$query = $input['query'];
$variables = isset($input['variables']) ? $input['variables'] : null;
$result = GraphQL::executeQuery(
$schema,
$query,
null,
null,
$variables
);
$output = $result->toArray();
} catch (\Exception $e) {
$output = [
'errors' => [
['message' => $e->getMessage()]
]
];
}
echo json_encode($output);
测试请求
curl -X POST http://your-server/graphql.php \
-H "Content-Type: application/json" \
-d '{
"query": "query { user(id: 1) { name email posts { title } } }"
}'
使用框架集成
Laravel + GraphQL PHP
// routes/api.php
Route::post('/graphql', function (\Illuminate\Http\Request $request) {
$schema = require app_path('graphql/schema.php');
$query = $request->input('query');
$variables = $request->input('variables', []);
$result = GraphQL::executeQuery($schema, $query, null, [], $variables);
return response()->json($result->toArray());
});
Symfony + OverblogGraphQLBundle
# config/packages/overblog_graphql.yaml
overblog_graphql:
definitions:
schema:
query: Query
mutation: Mutation
mappings:
types:
- types: [src/GraphQL/Type]
关键注意事项
- Schema 定义:明确定义类型、查询和变更
- Resolver 逻辑:每个 field 都有对应的解析函数
- 错误处理:适当处理和返回错误信息
- 性能优化:考虑 N+1 查询问题,使用 DataLoader
- 安全:做查询深度限制、查询复杂度分析
// 安全配置示例
$config = [
'query_complexity' => 100,
'query_depth' => 10,
'max_query_queries' => 100,
];
$result = GraphQL::executeQuery(
$schema,
$query,
null,
null,
$variables,
null,
null,
['query_complexity' => 100]
);
选择哪种方式取决于你的项目需求:
- 小型项目/学习:直接使用 webonyx/graphql-php
- Laravel 项目:使用 Lighthouse
- Symfony 项目:使用 OverblogGraphQLBundle
- 快速原型:可以考虑 GraphQLite