PHP解析GraphQL查询实战教程

GraphQL 是一种用于 API 的查询语言,它使得客户端能够精确地指定所需的数据结构。要在 PHP 中解析 GraphQL 查询,通常需要实现一个 GraphQL 服务器,能够接收、解析和执行 GraphQL 查询。

我们可以通过使用现有的 PHP 库来简化解析过程。最流行的 PHP GraphQL 库是 webonyx/graphql-php,这是一个功能强大的库,用于解析和执行 GraphQL 查询。

1. 安装 GraphQL PHP 库

首先,使用 Composer 安装 webonyx/graphql-php 库:

composer require webonyx/graphql-php

2. 设置 GraphQL Schema

GraphQL Schema 定义了你的 API 的数据模型和查询结构。我们需要定义类型、查询和解析器。

例子:定义简单的 Query 类型

<?php
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Schema;

require 'vendor/autoload.php';

// 定义一个简单的用户类型
$userType = new ObjectType([
    'name' => 'User',
    'fields' => [
        'id' => Type::id(),
        'name' => Type::string(),
        'email' => Type::string(),
    ],
]);

// 定义根查询类型
$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'user' => [
            'type' => $userType,
            'args' => [
                'id' => Type::nonNull(Type::id()),
            ],
            'resolve' => function ($rootValue, $args) {
                // 模拟从数据库获取数据
                $users = [
                    '1' => ['id' => '1', 'name' => 'John Doe', 'email' => 'john@example.com'],
                    '2' => ['id' => '2', 'name' => 'Jane Doe', 'email' => 'jane@example.com'],
                ];

                return $users[$args['id']] ?? null;
            }
        ]
    ]
]);

// 创建 GraphQL schema
$schema = new Schema([
    'query' => $queryType,
]);

?>

解析查询的核心代码

接下来,我们要解析并执行 GraphQL 查询。我们可以创建一个函数,解析来自客户端的 GraphQL 查询字符串,并执行查询。

<?php
use GraphQL\GraphQL;
use GraphQL\Language\Parser;
use GraphQL\Error\ErrorFormatter;
use GraphQL\Error\InvariantViolation;

function executeGraphQLQuery($queryString, $variables = null)
{
    global $schema;

    // 解析 GraphQL 查询字符串
    $document = Parser::parse($queryString);

    // 执行查询
    try {
        // 执行并返回结果
        $result = GraphQL::executeQuery($schema, $document, null, null, $variables);
        return $result->toArray();
    } catch (InvariantViolation $e) {
        return [
            'errors' => [
                [
                    'message' => $e->getMessage(),
                    'locations' => $e->getLocations(),
                    'path' => $e->getPath(),
                ]
            ]
        ];
    }
}

// 测试查询
$queryString = '{
  user(id: "1") {
    id
    name
    email
  }
}';

$response = executeGraphQLQuery($queryString);
echo json_encode($response, JSON_PRETTY_PRINT);
?>

在这个例子中,GraphQL 查询字符串是一个简单的查询,用于获取 id 为 “1” 的用户的 idname 和 emailexecuteGraphQLQuery() 函数负责解析并执行查询。

3. 执行查询并返回结果

在执行查询时,GraphQL 解析器会根据查询请求的字段来调用相应的解析器函数(在本例中是 resolve 函数)。查询的结果将以数组形式返回,然后我们将它以 JSON 格式输出。

执行上述代码后,你将看到类似以下的结果:

{
  "data": {
    "user": {
      "id": "1",
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
}

4. 处理查询中的错误

GraphQL 允许返回错误信息。当查询中出现错误时,它会将错误信息包装在 errors 字段中,并且查询数据会通过 data 字段返回。你可以根据查询执行结果来检查是否有错误。

例如,假设查询中请求了不存在的用户 ID:

$queryString = '{
  user(id: "3") {
    id
    name
    email
  }
}';

此时,执行结果将包含一个错误:

{
  "data": {
    "user": null
  },
  "errors": [
    {
      "message": "User not found",
      "locations": [{"line": 1, "column": 3}],
      "path": ["user"]
    }
  ]
}

5. 添加更多功能:变量、验证和身份验证

5.1 使用查询变量

GraphQL 允许使用变量来使查询更加灵活。你可以在查询中定义变量并在执行时提供它们。

例如:

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}

然后,在 PHP 中传递变量:

$queryString = 'query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}';

$variables = ['id' => '1'];
$response = executeGraphQLQuery($queryString, $variables);
echo json_encode($response, JSON_PRETTY_PRINT);

5.2 身份验证和授权

GraphQL 查询可以通过上下文来传递身份验证信息。你可以在解析器中获取上下文并使用它来检查用户是否有权访问某些数据。

$context = [
    'user' => $authenticatedUser,  // 模拟已认证的用户
];

$result = GraphQL::executeQuery($schema, $document, null, $context, $variables);

然后在解析器中:

'resolve' => function ($rootValue, $args, $context) {
    if ($context['user'] === null) {
        throw new \Exception('Unauthorized');
    }

    // 继续执行查询
    return $users[$args['id']] ?? null;
}

6. 部署和运行

将上述代码部署到你的服务器上,并确保你能够正确处理传入的 GraphQL 查询。你可以通过 HTTP 请求(如 POST 请求)来接收和处理 GraphQL 查询,通常在响应中返回 JSON 格式的查询结果。

总结

  • 使用 webonyx/graphql-php 库可以方便地在 PHP 中实现 GraphQL 查询的解析和执行。
  • 你可以通过定义 ObjectType 和 Schema 来构建你的 GraphQL 数据模型。
  • 使用 Parser 来解析 GraphQL 查询字符串,使用 GraphQL::executeQuery() 来执行查询。
  • 通过验证查询参数和实现安全措施(如身份验证),你可以确保 GraphQL API 的安全性。

通过这些步骤,你可以轻松地在 PHP 中实现一个简单的 GraphQL 服务器并解析查询。