news 2026/6/1 4:29:04

PHPGraphQLAPI实现与最佳实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHPGraphQLAPI实现与最佳实践

PHP GraphQL API实现与最佳实践

GraphQL是一种API查询语言,让客户端可以精确地获取需要的数据,不多不少。PHP中有多个GraphQL实现库,今天说说如何在PHP中搭建GraphQL服务。

GraphQL的核心概念是Schema、Query和Mutation。Schema定义了可查询的数据类型和操作。

```php
require 'vendor/autoload.php';

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Schema;
use GraphQL\GraphQL;

// 定义类型
$userType = new ObjectType([
'name' => 'User',
'fields' => [
'id' => Type::int(),
'name' => Type::string(),
'email' => Type::string(),
'age' => Type::int(),
'posts' => [
'type' => Type::listOf(fn() => $postType),
'resolve' => function ($user) {
return getPostsByUserId($user['id']);
},
],
],
]);

$postType = new ObjectType([
'name' => 'Post',
'fields' => [
'id' => Type::int(),
'title' => Type::string(),
'content' => Type::string(),
'author_id' => Type::int(),
'created_at' => Type::string(),
'author' => [
'type' => Type::listOf(fn() => $userType),
'resolve' => function ($post) {
return getUsers(['id' => $post['author_id']]);
},
],
],
]);

// 定义查询
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'user' => [
'type' => $userType,
'args' => [
'id' => Type::nonNull(Type::int()),
],
'resolve' => function ($root, $args) {
$users = getUsers(['id' => $args['id']]);
return $users[0] ?? null;
},
],
'users' => [
'type' => Type::listOf($userType),
'resolve' => function () {
return getUsers();
},
],
'post' => [
'type' => $postType,
'args' => [
'id' => Type::nonNull(Type::int()),
],
'resolve' => function ($root, $args) {
$posts = getPosts(['id' => $args['id']]);
return $posts[0] ?? null;
},
],
'posts' => [
'type' => Type::listOf($postType),
'args' => [
'author_id' => Type::int(),
],
'resolve' => function ($root, $args) {
if (isset($args['author_id'])) {
return getPostsByUserId($args['author_id']);
}
return getPosts();
},
],
],
]);

// 定义变更
$mutationType = new ObjectType([
'name' => 'Mutation',
'fields' => [
'createUser' => [
'type' => $userType,
'args' => [
'name' => Type::nonNull(Type::string()),
'email' => Type::nonNull(Type::string()),
'age' => Type::int(),
],
'resolve' => function ($root, $args) {
return createUser($args['name'], $args['email'], $args['age'] ?? null);
},
],
'updateUser' => [
'type' => $userType,
'args' => [
'id' => Type::nonNull(Type::int()),
'name' => Type::string(),
'email' => Type::string(),
'age' => Type::int(),
],
'resolve' => function ($root, $args) {
return updateUser($args['id'], $args);
},
],
'deleteUser' => [
'type' => Type::boolean(),
'args' => [
'id' => Type::nonNull(Type::int()),
],
'resolve' => function ($root, $args) {
return deleteUser($args['id']);
},
],
],
]);

// 模拟数据源
function getUsers(array $filter = []): array
{
$users = [
['id' => 1, 'name' => '张三', 'email' => 'zhangsan@test.com', 'age' => 28],
['id' => 2, 'name' => '李四', 'email' => 'lisi@test.com', 'age' => 35],
['id' => 3, 'name' => '王五', 'email' => 'wangwu@test.com', 'age' => 22],
];

if (isset($filter['id'])) {
return array_filter($users, fn($u) => $u['id'] === $filter['id']);
}

return $users;
}

function getPosts(array $filter = []): array
{
return [
['id' => 1, 'title' => 'PHP入门', 'content' => '内容1', 'author_id' => 1, 'created_at' => '2024-01-01'],
['id' => 2, 'title' => 'GraphQL基础', 'content' => '内容2', 'author_id' => 1, 'created_at' => '2024-01-15'],
['id' => 3, 'title' => '高级PHP', 'content' => '内容3', 'author_id' => 2, 'created_at' => '2024-02-01'],
];
}

function getPostsByUserId(int $userId): array
{
return array_filter(getPosts(), fn($p) => $p['author_id'] === $userId);
}

function createUser(string $name, string $email, ?int $age): array
{
return ['id' => 4, 'name' => $name, 'email' => $email, 'age' => $age ?? 0];
}

function updateUser(int $id, array $data): array
{
$users = getUsers(['id' => $id]);
if (empty($users)) throw new Exception("用户不存在");
return array_merge($users[0], $data);
}

function deleteUser(int $id): bool
{
return true;
}

// 处理GraphQL请求
$schema = new Schema([
'query' => $queryType,
'mutation' => $mutationType,
]);

$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'] ?? '';
$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);
?>
```

GraphQL的查询示例:

```graphql
// 查询示例
query {
user(id: 1) {
name
email
posts {
title
created_at
}
}
users {
name
age
}
}

// 变更示例
mutation {
createUser(name: "赵六", email: "zhao@test.com", age: 28) {
id
name
email
}
}
```

GraphQL相比REST API有几个优势。客户端精确控制返回字段,一次查询获取多个资源,强类型Schema提供自动文档。但GraphQL也有缺点,查询复杂度控制、缓存策略、文件上传等都比REST复杂。选择GraphQL还是REST取决于项目需求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 4:25:57

分布式图Transformer训练:GP-AG与GP-A2A策略解析与工程实践

1. 项目概述:当图Transformer遇上超大规模图如果你最近在折腾图神经网络,特别是想用图Transformer处理那些动辄百万节点、上亿边的大图,大概率会卡在单张GPU那可怜的内存上,或者对着动辄几天的训练时间发愁。我最近就在一个工业级…

作者头像 李华
网站建设 2026/6/1 4:25:03

从自动化到自主智能:构建情景感知的Self-Driving Phone实践指南

1. 项目概述:当手机学会“自己开车”“Self Driving Phones”——这个标题听起来有点科幻,但如果你把它理解为“让手机具备自主决策与执行任务的能力”,是不是瞬间就感觉触手可及了?这并非要给你的手机装上四个轮子,而…

作者头像 李华
网站建设 2026/6/1 4:24:22

低精度训练技术与StableSPAM优化器实践指南

1. 低精度训练技术概述在深度学习领域,低精度训练已经成为提升计算效率和降低硬件需求的关键技术。这项技术的核心在于通过减少数值表示的位宽来压缩模型大小和加速计算过程,同时尽可能保持模型的准确性能。1.1 低精度训练的基本原理低精度训练的核心思想…

作者头像 李华
网站建设 2026/6/1 4:23:04

PHP依赖注入容器原理与实现

PHP依赖注入容器原理与实现依赖注入是现代框架的核心。它让类之间的耦合降低,代码更容易测试和维护。今天从零实现一个依赖注入容器,理解它的工作原理。依赖注入的基本思想是:一个类需要的依赖由外部传入,而不是自己在内部创建。p…

作者头像 李华
网站建设 2026/6/1 4:18:27

AI智能体规模化工程实践:七层蓝图解决服务、安全与可观测性挑战

1. 项目概述:规模化AI智能体的服务、安全与可观测性蓝图最近和几个负责AI平台架构的朋友聊天,大家不约而同地提到了同一个痛点:单个AI智能体(Agent)的Demo跑起来很酷,但一旦要把它变成公司内部可复用的服务…

作者头像 李华
网站建设 2026/6/1 4:17:01

别再怕数学!用Arduino和AS5600磁编码器,一步步实现FOC力矩控制

别再怕数学!用Arduino和AS5600磁编码器,一步步实现FOC力矩控制当你想用无刷电机打造一个灵活的机器人关节或稳定的云台时,FOC(磁场定向控制)算法无疑是实现精准力矩控制的最佳选择。但对于大多数创客和嵌入式爱好者来说…

作者头像 李华