php graphql client

其他类别 2025-08-21

php graphql client

用PHP编写的GraphQL客户端,提供非常简单但功能强大的查询生成器类,使与GraphQl Server交互的过程非常简单。

用法

有3种主要方法可以使用此软件包生成您的GraphQl查询:

  1. 查询类:映射到GraphQl查询的简单类。它旨在轻松和速度操纵查询。
  2. QueryBuilder类:可动态生成Query对象的构建器类。在以动态方式构建查询的情况下,它将使用它。
  3. PHP GraphQL-OQM:此软件包的扩展名。它消除了编写任何GraphQl查询或参考API文档或语法的需求。它从API架构中生成查询对象,通过GraphQl的内省显示的声明,然后可以简单地与之相互作用。

安装

运行以下命令使用Composer安装软件包:

 $ composer require gmostafa/php-graphql-client

对象到Query-Mapper扩展

为了避免不得不编写任何查询的麻烦,只是与您的API架构生成的PHP对象进行交互

查询示例

简单查询

 $ gql = ( new Query ( ' companies ' ))
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

这个简单的查询将检索所有显示其姓名和序列号的公司。

完整的形式

上一个示例中提供的查询以“速记形式”表示。速记形式涉及编写减少的代码线,从而加快了搅拌Querries的过程。以下是上一个示例中完全相同的查询的完整表单的一个示例。

 $ gql = ( new Query ())
    -> setSelectionSet (
        [
            ( new Query ( ' companies ' ))
                -> setSelectionSet (
                    [
                        ' name ' ,
                        ' serialNumber '
                    ]
                )
        ]
    );

如示例所示,速记形式更简单地读写,与完整形式相比,它通常更喜欢使用。

除非无法以速记表单表示查询,否则不应使用完整的表单,当我们想在同一对象中运行多个查询时,只有一个情况。

多个查询

 $ gql = ( new Query ())
    -> setSelectionSet (
        [
            ( new Query ( ' companies ' ))
            -> setSelectionSet (
                [
                    ' name ' ,
                    ' serialNumber '
                ]
            ),
            ( new Query ( ' countries ' ))
            -> setSelectionSet (
                [
                    ' name ' ,
                    ' code ' ,
                ]
            )
        ]
    );

此查询会检索所有公司和国家 /地区都显示每个数据字段。它基本上在一个查询对象信封中运行两个(或更多)独立查询。

编写多个查询需要以完整形式编写查询对象,以将每个查询表示为父级查询对象下的子字段。

嵌套查询

 $ gql = ( new Query ( ' companies ' ))
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber ' ,
            ( new Query ( ' branches ' ))
                -> setSelectionSet (
                    [
                        ' address ' ,
                        ( new Query ( ' contracts ' ))
                            -> setSelectionSet ([ ' date ' ])
                    ]
                )
        ]
    );

此查询是一个更复杂的查询,不仅可以检索标量字段,还可以检索对象字段。此查询将返回所有公司,显示其姓名,序列号,以及每个公司,其所有分支机构,显示分支机构地址,每个地址为每个地址,它检索到该地址的所有合同,并显示其日期。

查询参数

 $ gql = ( new Query ( ' companies ' ))
    -> setArguments ([ ' name ' => ' Tech Co. ' , ' first ' => 3 ])
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

此查询不会通过添加参数来检索所有公司。该查询将以“ Tech Co.”的名称检索前三家公司,并显示其名称和序列号。

与数组参数查询

 $ gql = ( new Query ( ' companies ' ))
    -> setArguments ([ ' serialNumbers ' => [ 159 , 260 , 371 ]])
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

此查询是参数查询的特殊情况。在此示例中,查询将仅在159、260和371之一中检索具有序列号的公司,显示名称和序列号。

使用输入对象参数查询

setSelectionSet( [ 'name', 'serialNumber' ] );">
 $ gql = ( new Query ( ' companies ' ))
    -> setArguments ([ ' filter ' => new RawObject ( ' {name_starts_with: "Face"} ' )])
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

此查询是参数查询的另一个特殊情况。在此示例中,我们将设置一个具有一些值的自定义输入对象“过滤器”,以限制返回的公司。我们将使用值“ face”设置过滤器“ name_starts_with”。此查询将仅检索名称以“ face”为开头的公司。

构造的Rawobject类用于将字符串注入查询中。任何字符串输入到Rawobject构造器中,都将放入查询中,因为它通常没有任何自定义格式,通常是通过查询类完成的。

查询变量

 $ gql = ( new Query ( ' companies ' ))
    -> setVariables (
        [
            new Variable ( ' name ' , ' String ' , true ),
            new Variable ( ' limit ' , ' Int ' , false , 5 )
        ]
    )
    -> setArguments ([ ' name ' => ' $name ' , ' first ' => ' $limit ' ])
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

此查询显示了如何在此软件包中使用变量以允许GraphQL标准启用动态请求。

变量类

变量类是一个不变的类,代表GraphQL标准中的变量。它的构造函数收到4个参数:

  • 名称:代表变量名称
  • 类型:根据GraphQL Server架构表示变量类型
  • iSrequired(可选):表示是否需要该变量,默认情况下是错误的
  • DefaultValue(可选):表示要分配给变量的默认值。仅当将ISREQUIRED参数设置为false时,才会考虑默认值。

使用别名

 $ gql = ( new Query ())
    -> setSelectionSet (
        [
            ( new Query ( ' companies ' , ' TechCo ' ))
                -> setArguments ([ ' name ' => ' Tech Co. ' ])
                -> setSelectionSet (
                    [
                        ' name ' ,
                        ' serialNumber '
                    ]
                ),
            ( new Query ( ' companies ' , ' AnotherTechCo ' ))
                -> setArguments ([ ' name ' => ' A.N. Other Tech Co. ' ])
                -> setSelectionSet (
                    [
                        ' name ' ,
                        ' serialNumber '
                    ]
                )
        ]
    );

在需要多次以不同参数检索相同对象的情况下,可以在查询构造函数的第二个参数中设置别名。

 $ gql = ( new Query ( ' companies ' ))
    -> setAlias ( ' CompanyAlias ' )
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );

别名也可以通过设置方法设置。

使用接口:与内联片段查询

查询返回接口类型的字段时,您可能需要使用内联片段来访问基础混凝土类型的数据。

此示例显示了如何使用此软件包生成内联片段:

 $ gql = new Query ( ' companies ' );
$ gql -> setSelectionSet (
    [
        ' serialNumber ' ,
        ' name ' ,
        ( new InlineFragment ( ' PrivateCompany ' ))
            -> setSelectionSet (
                [
                    ' boardMembers ' ,
                    ' shareholders ' ,
                ]
            ),
    ]
);

查询构建器

QueryBuilder类可用于动态构造查询对象,在某些情况下这很有用。它的工作原理与查询类非常相似,但是查询建筑物分为步骤。

这就是可以使用QueryBuilder创建“使用输入对象参数的查询”示例的方式:

 $ builder = ( new QueryBuilder ( ' companies ' ))
    -> setVariable ( ' namePrefix ' , ' String ' , true )
    -> setArgument ( ' filter ' , new RawObject ( ' {name_starts_with: $namePrefix} ' ))
    -> selectField ( ' name ' )
    -> selectField ( ' serialNumber ' );
$ gql = $ builder -> getQuery ();

与查询类一样,可以使用第二个构造函数参数设置别名。

 $ builder = ( new QueryBuilder ( ' companies ' , ' CompanyAlias ' ))
    -> selectField ( ' name ' )
    -> selectField ( ' serialNumber ' );

$ gql = $ builder -> getQuery ();

或通过Setter方法

 $ builder = ( new QueryBuilder ( ' companies ' ))
    -> setAlias ( ' CompanyAlias ' )
    -> selectField ( ' name ' )
    -> selectField ( ' serialNumber ' );

$ gql = $ builder -> getQuery ();

完整的形式

就像查询类一样,可以完整地编写QueryBuilder类,以在一个查询构建器对象下编写多个查询。以下是一个示例,说明如何将完整表单与QueryBuilder一起使用:

 $ builder = ( new QueryBuilder ())
    -> setVariable ( ' namePrefix ' , ' String ' , true )
    -> selectField (
        ( new QueryBuilder ( ' companies ' ))
            -> setArgument ( ' filter ' , new RawObject ( ' {name_starts_with: $namePrefix} ' ))
            -> selectField ( ' name ' )
            -> selectField ( ' serialNumber ' )
    )
    -> selectField (
        ( new QueryBuilder ( ' company ' ))
            -> setArgument ( ' serialNumber ' , 123 )
            -> selectField ( ' name ' )
    );
$ gql = $ builder -> getQuery ();

此查询是上一个示例中查询的扩展。它返回所有以名称前缀开头的公司,并以相同的响应返回了价值123的serialNumber名单。

构建客户

通过提供GraphQl端点URL可以轻松实例化客户端对象。

客户端构造函数还接收一个可选的“授权台面”数组,可用于将授权标头添加到发送到GraphQL Server的所有请求中。

例子:

 $ client = new Client (
    ' http://api.g*r*ap*hql.com ' ,
    [ ' Authorization ' => ' Basic xyz ' ]
);

客户端构造函数还接收一个可选的“ HTTPoptions”数组,该数组覆盖了“授权头”,可用于添加自定义Guzles HTTP http client Request request选项。

例子:

'tcp://localhost:9124', // Use this proxy with "https", 'no' => ['.mit.edu', 'foo.com'] // Don't use a proxy with these ], 'cert' => ['/path/server.pem', 'password'] ... ] );">
 $ client = new Client (
    ' http://api.g*r*ap*hql.com ' ,
    [],
    [ 
        ' connect_timeout ' => 5 ,
        ' timeout ' => 5 ,
        ' headers ' => [
            ' Authorization ' => ' Basic xyz '
            'User-Agent' => ' testing/1.0 ' ,
        ],
        ' proxy ' => [
                ' http '  => ' tcp://localhost:8125 ' , // Use this proxy with "http"
                ' https ' => ' tcp://localhost:9124 ' , // Use this proxy with "https",
                ' no ' => [ ' .mit.edu ' , ' foo.com ' ]    // Don't use a proxy with these
        ],
        ' cert ' => [ ' /path/server.pem ' , ' password ' ]
        . . .
    ]
);

可以使用您自己的预先配置的HTTP客户端来实现PSR-18接口。

例子:

 $ client = new Client (
    ' http://api.g*r*ap*hql.com ' ,
    [],
    [],
    $ myHttpClient
);

运行查询

结果格式

使用GraphQL客户端运行查询并在对象结构中获取结果:

 $ results = $ client -> runQuery ( $ gql );
$ results -> getData ()-> companies [ 0 ]-> branches ;

或获得阵列结构的结果:

 $ results = $ client -> runQuery ( $ gql , true );
$ results -> getData ()[ ' companies ' ][ 1 ][ ' branches ' ][ ' address ' ];

将变量传递给查询

运行包含变量的查询需要传递一个关联数组,该数组将变量名(键)映射到变量值(值)到runQuery方法。这是一个例子:

 $ gql = ( new Query ( ' companies ' ))
    -> setVariables (
        [
            new Variable ( ' name ' , ' String ' , true ),
            new Variable ( ' limit ' , ' Int ' , false , 5 )
        ]
    )
    -> setArguments ([ ' name ' => ' $name ' , ' first ' => ' $limit ' ])
    -> setSelectionSet (
        [
            ' name ' ,
            ' serialNumber '
        ]
    );
$ variablesArray = [ ' name ' => ' Tech Co. ' , ' first ' => 5 ];
$ results = $ client -> runQuery ( $ gql , true , $ variablesArray );

突变

突变遵循GraphQL中相同的查询规则,它们在返回的对象上选择字段,接收参数,并且可以具有子场。

这是有关如何构建和运行突变的示例示例:

setSelectionSet( [ '_id', 'name', 'serialNumber', ] ); $results = $client->runQuery($mutation);">
 $ mutation = ( new Mutation ( ' createCompany ' ))
    -> setArguments ([ ' companyObject ' => new RawObject ( ' {name: "Trial Company", employees: 200} ' )])
    -> setSelectionSet (
        [
            ' _id ' ,
            ' name ' ,
            ' serialNumber ' ,
        ]
    );
$ results = $ client -> runQuery ( $ mutation );

可以通过客户端运行的方式运行突变。

变量的突变示例

突变可以以相同的查询方式利用变量。这是如何使用变量将输入对象传递到GraphQl Server的一个示例:

 $ mutation = ( new Mutation ( ' createCompany ' ))
    -> setVariables ([ new Variable ( ' company ' , ' CompanyInputObject ' , true )])
    -> setArguments ([ ' companyObject ' => ' $company ' ]);

$ variables = [ ' company ' => [ ' name ' => ' Tech Company ' , ' type ' => ' Testing ' , ' size ' => ' Medium ' ]];
$ client -> runQuery (
    $ mutation , true , $ variables
);

这些是由此产生的突变,随之而来的变量:

mutation( $ company : CompanyInputObject!) {
  createCompany (companyObject: $ company )
}
{"company":{"name":"Tech Company", " type " :"Testing", " size " :"Medium"}}

实时API示例

GraphQl Pokemon是一种非常酷的公共GraphQl API,可用于检索口袋妖怪数据。 API在网络上公开可用,我们将使用它来演示该客户端的功能。

github repo链接:https://github.com/lucasbento/graphql-pokemon

API链接:https://graphql-pokemon.now.sh/

此查询检索了任何口袋妖怪的演变及其攻击:

query( $ name : String!) {
  pokemon (name: $ name ) {
    id
    number
    name
    evolutions {
      id
      number
      name
      weight {
        minimum
        maximum
      }
      attacks {
        fast {
          name
          type
          damage
        }
      }
    }
  }
}

这就是可以使用查询类编写此查询并使用客户端运行的方式:

 $ client = new Client (
    ' https://graphql-pokemon.*n*o*w.sh/ '
);
$ gql = ( new Query ( ' pokemon ' ))
    -> setVariables ([ new Variable ( ' name ' , ' String ' , true )])
    -> setArguments ([ ' name ' => ' $name ' ])
    -> setSelectionSet (
        [
            ' id ' ,
            ' number ' ,
            ' name ' ,
            ( new Query ( ' evolutions ' ))
                -> setSelectionSet (
                    [
                        ' id ' ,
                        ' number ' ,
                        ' name ' ,
                        ( new Query ( ' attacks ' ))
                            -> setSelectionSet (
                                [
                                    ( new Query ( ' fast ' ))
                                        -> setSelectionSet (
                                            [
                                                ' name ' ,
                                                ' type ' ,
                                                ' damage ' ,
                                            ]
                                        )
                                ]
                            )
                    ]
                )
        ]
    );
try {
    $ name = readline ( ' Enter pokemon name: ' );
    $ results = $ client -> runQuery ( $ gql , true , [ ' name ' => $ name ]);
}
catch ( QueryError $ exception ) {
    print_r ( $ exception -> getErrorDetails ());
    exit ;
}
print_r ( $ results -> getData ()[ ' pokemon ' ]);

或者,这就是可以使用QueryBuilder类生成此查询的方式:

 $ client = new Client (
    ' https://graphql-pokemon.*n*o*w.sh/ '
);
$ builder = ( new QueryBuilder ( ' pokemon ' ))
    -> setVariable ( ' name ' , ' String ' , true )
    -> setArgument ( ' name ' , ' $name ' )
    -> selectField ( ' id ' )
    -> selectField ( ' number ' )
    -> selectField ( ' name ' )
    -> selectField (
        ( new QueryBuilder ( ' evolutions ' ))
            -> selectField ( ' id ' )
            -> selectField ( ' name ' )
            -> selectField ( ' number ' )
            -> selectField (
                ( new QueryBuilder ( ' attacks ' ))
                    -> selectField (
                        ( new QueryBuilder ( ' fast ' ))
                            -> selectField ( ' name ' )
                            -> selectField ( ' type ' )
                            -> selectField ( ' damage ' )
                    )
            )
    );
try {
    $ name = readline ( ' Enter pokemon name: ' );
    $ results = $ client -> runQuery ( $ builder , true , [ ' name ' => $ name ]);
}
catch ( QueryError $ exception ) {
    print_r ( $ exception -> getErrorDetails ());
    exit ;
}
print_r ( $ results -> getData ()[ ' pokemon ' ]);

运行原始查询

尽管不是此软件包的主要目标,但它支持运行原始的字符串查询,就像使用Client端类中的runRawQuery方法一样的其他客户端。这是如何使用它的示例:

 $ gql = <<
query {
    pokemon(name: "Pikachu") {
        id
        number
        name
        attacks {
            special {
                name
                type
                damage
            }
        }
    }
}
QUERY ;

$ results = $ client -> runRawQuery ( $ gql );
下载源码

通过命令行克隆项目:

git clone https://github.com/mghoneimy/php-graphql-client.git