在 PHP 8 中实践 GraphQL,可以通过使用现有的 GraphQL 库(如 Webonyx/GraphQL-PHP)来实现服务端的 GraphQL API。以下是关于如何在 PHP 8 中实现 GraphQL 的完整实践步骤。


webonyx/graphql-php
https://github.com/webonyx/graphql-php/

Doc
https://webonyx.github.io/graphql-php/

Examples
https://github.com/webonyx/graphql-php/tree/master/examples

1. 安装依赖

在 PHP 中实现 GraphQL,推荐使用 Webonyx/GraphQL-PHP,它是一个功能强大的 GraphQL PHP 库。

使用 Composer 安装:

composer require webonyx/graphql-php

2. 构建 Schema

GraphQL 的核心是 Schema,它定义了 API 的数据结构和交互方式。我们需要先构建 GraphQL 的 Schema。

示例: 定义一个简单的用户查询

假设我们有一个用户数据结构,包含 idnameemail,我们将创建一个简单的 GraphQL 查询来获取用户信息。

创建 Schema 文件

在 PHP 中,Schema 使用 GraphQL\Type\Schema 和相关类型(如 GraphQL\Type\Definition\ObjectType)来定义。

创建 UserType(定义用户类型)

// src/Types/UserType.php
<?php

namespace App\Types;

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

class UserType extends ObjectType
{
    public function __construct()
    {
        $config = [
            'name' => 'User',
            'fields' => [
                'id' => Type::nonNull(Type::id()),
                'name' => Type::string(),
                'email' => Type::string(),
            ],
        ];
        parent::__construct($config);
    }
}

定义查询类型 (QueryType)

我们需要创建一个 QueryType,允许客户端通过查询获取用户数据。

// src/Types/QueryType.php
<?php

namespace App\Types;

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

class QueryType extends ObjectType
{
    public function __construct()
    {
        $config = [
            'name' => 'Query',
            'fields' => [
                'user' => [
                    'type' => new UserType(),
                    'args' => [
                        'id' => Type::nonNull(Type::id()),
                    ],
                    'resolve' => function ($root, $args) {
                        // 模拟一个用户数据(实际应用中可以从数据库中获取)
                        $users = [
                            1 => ['id' => 1, 'name' => 'Alice', 'email' => '[email protected]'],
                            2 => ['id' => 2, 'name' => 'Bob', 'email' => '[email protected]'],
                        ];

                        return $users[$args['id']] ?? null;
                    }
                ],
            ],
        ];
        parent::__construct($config);
    }
}

创建 Schema

最后,使用 QueryType 创建 Schema。

// src/Schema.php
<?php

namespace App;

use App\Types\QueryType;
use GraphQL\Type\Schema;

class GraphQLSchema
{
    public static function build(): Schema
    {
        return new Schema([
            'query' => new QueryType(),
        ]);
    }
}

3. **设置服务器端点

**
GraphQL 通常运行在一个单独的端点上,例如 /graphql。我们需要设置一个 PHP 脚本来处理 GraphQL 查询。

创建 GraphQL Server

// public/index.php
<?php

require_once __DIR__ . '/../vendor/autoload.php';

use GraphQL\GraphQL;
use GraphQL\Error\FormattedError;
use GraphQL\Error\DebugFlag;
use App\GraphQLSchema;

// 启用错误展示(仅在开发环境下)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// 获取请求的 GraphQL 查询
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'] ?? '';
$variables = $input['variables'] ?? null;

try {
    // 创建 Schema
    $schema = GraphQLSchema::build();

    // 执行 GraphQL 查询
    $result = GraphQL::executeQuery($schema, $query, null, null, $variables);
    $output = $result->toArray(DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACE);
} catch (\Exception $e) {
    // 格式化错误
    $output = [
        'errors' => [
            FormattedError::createFromException($e)
        ]
    ];
}

// 设置返回头
header('Content-Type: application/json');
echo json_encode($output);

4. 测试 GraphQL API

你现在可以运行 PHP 内置的开发服务器,测试 GraphQL API。

启动开发服务器

php -S localhost:8000 -t public

服务器端点为 http://localhost:8000

示例 GraphQL 查询

使用一个工具(如 GraphiQL 或 Postman)发送如下请求:

URL: http://localhost:8000
方法: POST
请求体:

{
  "query": "query GetUser($id: ID!) { user(id: $id) { id name email } }",
  "variables": { "id": 1 }
}

响应:

{
  "data": {
    "user": {
      "id": "1",
      "name": "Alice",
      "email": "[email protected]"
    }
  }
}

5. 添加 Mutations(可选)

为了支持数据的增删改操作,可以在 Schema 中定义 Mutation 类型。

示例:创建用户 Mutation

更新 MutationType

// src/Types/MutationType.php
<?php

namespace App\Types;

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

class MutationType extends ObjectType
{
    private $users = [];

    public function __construct()
    {
        $config = [
            'name' => 'Mutation',
            'fields' => [
                'createUser' => [
                    'type' => new UserType(),
                    'args' => [
                        'name' => Type::nonNull(Type::string()),
                        'email' => Type::nonNull(Type::string()),
                    ],
                    'resolve' => function ($root, $args) {
                        // 处理用户创建逻辑(这里是模拟逻辑)
                        $newUser = [
                            'id' => rand(1, 1000),
                            'name' => $args['name'],
                            'email' => $args['email'],
                        ];
                        return $newUser;
                    },
                ],
            ],
        ];
        parent::__construct($config);
    }
}

更新 Schema

更新 Schema 以包含 Mutation:

// src/Schema.php
<?php

namespace App;

use App\Types\QueryType;
use App\Types\MutationType;
use GraphQL\Type\Schema;

class GraphQLSchema
{
    public static function build(): Schema
    {
        return new Schema([
            'query' => new QueryType(),
            'mutation' => new MutationType(),
        ]);
    }
}

总结

以上是一个在 PHP 8 中实现 GraphQL 的基础实践案例,使用 webonyx/graphql-php 提供了强大的工具支持。通过以下步骤,你可以实现一个功能齐全的 GraphQL API:

  1. 定义 Schema(包含 Query 和 Mutation)。
  2. 编写解析器(Resolver)处理逻辑。
  3. 创建服务器端点接收和处理 GraphQL 请求。
  4. 使用工具测试 GraphQL API。

可以根据业务需求扩展更多的功能,如认证、复杂查询、订阅等。

标签: PHP, GraphQL

评论已关闭