溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

PHP中怎么安裝和使用GraphQL

發(fā)布時(shí)間:2021-05-08 10:11:58 來(lái)源:億速云 閱讀:223 作者:小新 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)PHP中怎么安裝和使用GraphQL,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

php是什么語(yǔ)言

php,一個(gè)嵌套的縮寫(xiě)名稱,是英文超級(jí)文本預(yù)處理語(yǔ)言(PHP:Hypertext Preprocessor)的縮寫(xiě)。PHP 是一種 HTML 內(nèi)嵌式的語(yǔ)言,PHP與微軟的ASP頗有幾分相似,都是一種在服務(wù)器端執(zhí)行的嵌入HTML文檔的腳本語(yǔ)言,語(yǔ)言的風(fēng)格有類似于C語(yǔ)言,現(xiàn)在被很多的網(wǎng)站編程人員廣泛的運(yùn)用。

關(guān)于 GraphQL

GraphQL 是一種現(xiàn)代化的 HTTP API 接口構(gòu)建方式,客戶端可以按需查詢需要的數(shù)據(jù)。
GraphQL 可以提升 API 調(diào)用的靈活性,我們可以像寫(xiě)數(shù)據(jù)庫(kù)查詢語(yǔ)句一樣來(lái)請(qǐng)求 API 來(lái)獲取所需要的數(shù)據(jù),這對(duì)構(gòu)建復(fù)雜的 API 查詢來(lái)說(shuō)非常有用。

與REST對(duì)比

REST的核心思想就是資源,每個(gè)資源都能用一個(gè)URL來(lái)表示,你能通過(guò)一個(gè)GET請(qǐng)求訪問(wèn)該URL從而獲取該資源。根據(jù)當(dāng)今大多數(shù)API的定義,你很有可能會(huì)得到一份JSON格式的數(shù)據(jù)響應(yīng),整個(gè)過(guò)程大概是這樣:

GET /user/1
{
    "username":"姓名",
    "age":20,
    "sex":"男"
}
GET /book/1
{
    "book":"書(shū)名",
    "author":"作者",
    "country":"中國(guó)"
}

從上面的示例可以看出,如果前端需要user/1book/1的時(shí)候需要調(diào)用2次接口,并且如果前端只需要user/1里面的username,而上面的接口獲取了username以外的數(shù)據(jù),那么對(duì)于前端而言,除 username 之外的數(shù)據(jù)無(wú)處可用,造成了資源的浪費(fèi)。

如果我們使用GraphQL來(lái)進(jìn)行查詢的話,與REST方式相比,只需要調(diào)用一次并且可以查詢我們指定的字段,避免了資源的浪費(fèi),并且更加高效。

query {
 user(id:1) {
     username
 }
 book(id:1){
     book,
     author,
     country
 }
}

推薦學(xué)習(xí):《PHP視頻教程》

安裝graphql-php包

composer require webonyx/graphql-php

開(kāi)始

1、安裝完成之后,我們先編寫(xiě)一個(gè)簡(jiǎn)單示例,來(lái)看看graphql-php怎么用,具體代碼如下:這段代碼中,我們定義了一個(gè)名為phoneNumber的字段,然后通過(guò)postman來(lái)調(diào)用我們編寫(xiě)的代碼。

<?php
require_once __DIR__ . '/vendor/autoload.php';
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\GraphQL;

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'phoneNumber' => [
            'type' => Type::int(),
            'resolve' => function () {
                return 1875555555;
            }
        ]
    ],
]);

$schema = new Schema([
    'query' => $queryType,
]);



$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);

$query = $input['query'];
$variableValues = isset($input['variables']) ? $input['variables'] : null;

try {
    $rootValue = ['prefix' => 'prefix: '];
    $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
    $output = $result->toArray();
} catch (\Exception $e) {

    $output = [
        'errors' => [
            [
                'message' => $e->getMessage()
            ]
        ]
    ];
}
header('Content-Type: application/json');
echo json_encode($output);

2、使用postman來(lái)調(diào)用我們剛剛編寫(xiě)的代碼,以下是我們查詢結(jié)果的示例

PHP中怎么安裝和使用GraphQL

介紹

從上面的示例中,我們可以看到示例主要引入了4個(gè)類

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

Schema 類

Schema 是類型層次結(jié)構(gòu)的容器,它接受構(gòu)造函數(shù)中的根類型并向內(nèi)部 GrahpQL 工具提供接收你的類型信息的方法。

配置選項(xiàng)

包含以下選項(xiàng)的數(shù)組:

OptionTypeNotes
queryObjectType必須。 讀取 API 中包含根級(jí)字段的對(duì)象類型 (通常命名為 "Query"),用于讀取數(shù)據(jù)
mutationObjectType寫(xiě)入 API 中包含根級(jí)字段的對(duì)象類型  (通常命名為 "Mutation"),數(shù)據(jù)變更時(shí)會(huì)用到
subscriptionObjectType保留用于將來(lái)的描述實(shí)現(xiàn)。目前表現(xiàn)為 graphql-js 自檢查詢的兼容,用于各種客戶端 (如 Relay 或 GraphiQL)
directivesDirective[]默認(rèn)包含內(nèi)建指令 @skip@include 。

如果你傳遞自定義指令并且依然想使用內(nèi)建指令,請(qǐng)聲明添加它們。例如:

array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]);
typesObjectType[]對(duì)象類型類表,它在靜態(tài) schema 解析期間是不能被 graphql-php 發(fā)現(xiàn)的。

大多數(shù)情況下,對(duì)象類型未曾在字段中被直接引用,但它依然是 schema 的一部分時(shí)會(huì)用到,因?yàn)樗鼘?shí)現(xiàn)了一個(gè)在 resolveType 中調(diào)用解析為此對(duì)象類型的接口。

請(qǐng)注意,您在此處無(wú)需傳遞所有類型 ,它只是具體用例的解決方法。
typeLoadercallablefunction($name) 返回給定的類型實(shí)例名稱。 多次調(diào)用情況下,必須返回同樣的實(shí)例。 查閱下文延遲類型加載部分。

ObjectType類

GraphQL\Type\Definition\ObjectType

對(duì)象類型是典型的 GraphQL 應(yīng)用程序中使用最頻繁的基元。

配置選項(xiàng)
OptionTypeNotes
namestring必須。 Schema 中此對(duì)象的唯一名稱
fieldsarray or callable必須。 描述對(duì)象字段或可調(diào)用返回此類數(shù)組的數(shù)組。
descriptionstring呈現(xiàn)于客戶端的參數(shù)文本說(shuō)明(例如:用于 GraphiQL 自動(dòng)生成文檔 )
interfacesarray or callable此類型實(shí)現(xiàn)的接口列表或返回此類列表的可調(diào)用接口。
內(nèi)置標(biāo)量類型
<?php
use GraphQL\Type\Definition\Type;
// 內(nèi)置標(biāo)量類型
Type::string();  // String 類型
Type::int();     // Int 類型
Type::float();   // Float 類型
Type::boolean(); // Boolean 類型
Type::id();      // ID 類型

字段參數(shù)

GraphQL 對(duì)象類型上的所有字段都有 0 個(gè)或多個(gè)參數(shù),使用在 args 的字段定義上。每個(gè)參數(shù)數(shù)組參考以下說(shuō)明:

OptionTypeNotes
namestring必須。 參數(shù)名稱。 為空時(shí),使用 args 數(shù)組鍵值
typeType必須。
descriptionstring呈現(xiàn)于客戶端的參數(shù)文本說(shuō)明
defaultValuescalar當(dāng)前參數(shù)默認(rèn)值

示例

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'phoneNumber' => [
            'type' => Type::int(),
            'resolve' => function () {
                return 1875555555;
            }
        ]
    ],
]);

GraphQL 類

GraphQL類主要在查詢的時(shí)候用到,我們可以用 GraphQL::executeQuery 方法來(lái)執(zhí)行查詢

executeQuery 方法的參數(shù)說(shuō)明

參數(shù)類型說(shuō)明
schemaGraphQL\Type\Schema必須。  Schema應(yīng)用實(shí)例
queryStringstring or GraphQL\Language\AST\DocumentNode必須。 解析,驗(yàn)證并執(zhí)行現(xiàn)有的 GraphQL 查詢字符。 如果在執(zhí)行之前解析其他查詢,則在此處傳遞相應(yīng)的 AST 文檔節(jié)點(diǎn)來(lái)避免新的解析。
rootValuemixed表示數(shù)據(jù)圖結(jié)構(gòu)的基礎(chǔ)值。作為Query type 字段解析傳遞的第一個(gè)參數(shù)。如果現(xiàn)有該值已被 Query type 解析過(guò),則可忽略或設(shè)置為 null 值。
contextmixed字段解析器的共享信息。 常用來(lái)傳遞已登錄用戶信息,位置詳情等。

它將用在所有字段解析器的第 3 個(gè)參數(shù)。
variableValuesarray變量的映射,該值將隨同查詢字符串一起傳遞。請(qǐng)查閱 GraphQL官網(wǎng)查詢變量的相關(guān)。
operationNamestring指定請(qǐng)求方可執(zhí)行的操作, 防止條件查詢字符包含多級(jí)操作。
fieldResolvercallableSchema 參數(shù) schema 中未實(shí)現(xiàn)的解析器函數(shù)。
validationRulesarray查詢驗(yàn)證規(guī)則組,默認(rèn)所有規(guī)則??諗?shù)組將跳過(guò)查詢驗(yàn)證 (對(duì)于持久化查詢將會(huì)比較方便,查詢會(huì)在持久化之前默認(rèn)已驗(yàn)證,并在執(zhí)行期間假設(shè)符合規(guī)則)。
use GraphQL\GraphQL;

$result = GraphQL::executeQuery(
    $schema, 
    $queryString, 
    $rootValue = null, 
    $context = null, 
    $variableValues = null, 
    $operationName = null,
    $fieldResolver = null,
    $validationRules = null
);

簡(jiǎn)單示例

我們介紹完GraphQL幾個(gè)概念之后,用幾個(gè)簡(jiǎn)單的示例帶大家來(lái)體驗(yàn)一下。

普通示例

在這個(gè)示例中我們定義了2個(gè)字段,分別是phoneNumberecho,其中phoneNumber為 Type::int()類型,echoType::string()類型,同時(shí)echo字段帶有一個(gè)參數(shù)為message

<?php

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

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

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'phoneNumber' => [
            'type' => Type::int(),
            'resolve' => function () {
                return 1875555555;
            }
        ],

        'echo' => [
            'type' => Type::string(),
            'args' => [
                'message' => Type::string(),
            ],
            'resolve' => function ($root, $args) {
                return 'echo msg result:' . ($args['message'] ?? 'nothing');
            }
        ],
    ],
]);

$schema = new Schema([
    'query' => $queryType
]);


$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);

$query = $input['query'];
$variableValues = isset($input['variables']) ? $input['variables'] : null;

try {
    $rootValue = ['prefix' => 'prefix: '];
    $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
    $output = $result->toArray();
} catch (\Exception $e) {

    $output = [
        'errors' => [
            [
                'message' => $e->getMessage()
            ]
        ]
    ];
}
header('Content-Type: application/json');
echo json_encode($output);
執(zhí)行示例代碼結(jié)果

PHP中怎么安裝和使用GraphQL

我們可以看到,在請(qǐng)求時(shí)我們傳了phoneNumberecho兩個(gè)字段,并且messagetest。

對(duì)象示例

我們?cè)谏厦嬲f(shuō)過(guò),對(duì)象類型是典型的 GraphQL 應(yīng)用程序中使用最頻繁的基元,一個(gè)對(duì)象類型里面可以包含寧外一個(gè)對(duì)象類型,我們可以新定義一個(gè)名為$userTypeObjectType,然后在oneUser指定它的類型為$userType,這樣我們執(zhí)行查詢的時(shí)候,oneUser就會(huì)返回一個(gè)對(duì)象。

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

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

$userType = new ObjectType([
    'name' => 'userType',
    'description' => '用戶詳情',
    'fields' => [
        'uid' => [
            'type' => Type::int(),
            'description' => '用戶ID'
        ],
        'name' => Type::string()
    ]
]);


$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'oneUser' => [
            'type' => $userType, // 我們這里指定type為我們上面創(chuàng)建的$userType
            'description' => '用戶列表',
            'args' => [
                'uid' => [
                    'type' => Type::int(),
                    'defaultValue' => 222
                ]
            ],
            'resolve' => function($root, $args) {
                return  [
                    "uid" => $args['user_id'] ?? 3,
                    "name" => "xzl",
                ];
            }
        ],
    ]
]);

$schema = new Schema([
    'query' => $queryType
]);

$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'];
$variableValues = isset($input['variables']) ? $input['variables'] : null;

try {
    $rootValue = ['prefix' => 'prefix: '];
    $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
    $output = $result->toArray();
} catch (\Exception $e) {
    $output = [
        'errors' => [
            [
                'message' => $e->getMessage()
            ]
        ]
    ];
}
header('Content-Type: application/json');
echo json_encode($output);
執(zhí)行示例代碼結(jié)果

PHP中怎么安裝和使用GraphQL

列表示例

在平時(shí)的開(kāi)發(fā)請(qǐng)求中,我們從后端接口獲取數(shù)據(jù)的時(shí)候,大部分都是以列表的形式返回的,我們可以通過(guò)Type::listOf方法來(lái)指定我們返回的字段是一個(gè)列表。

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

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

class User
{
    // 模擬從數(shù)據(jù)庫(kù)取數(shù)據(jù)
    public static function getUserLimit($limit)
    {
        $user  = [
            [
                "uid" => 1,
                "name" => "name1"
            ],
            [
                "uid" => 2,
                "name" => "name2"
            ],
            [
                "uid" => 3,
                "name" => "name3"
            ],
            [
                "uid" => 4,
                "name" => "name4"
            ]
        ];
        return array_slice($user, 0, $limit);
    }
}


$userType = new ObjectType([
    'name' => 'userType',
    'description' => '用戶詳情',
    'fields' => [
        'uid' => [
            'type' => Type::int(),
            'description' => '用戶ID'
        ],
        'name' => Type::string()
    ]
]);


$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'users' => [
            'type' => Type::listOf($userType),
            'description' => '用戶列表',
            'args' => [
                'limit' => [
                    'type' => Type::int(),
                    'description' => '限制條數(shù)',
                    'defaultValue' => 10
                ]
            ],
            'resolve' => function($root, $args) {
                return User::getUserLimit($args['limit']);
            }
        ]
    ]
]);



$schema = new Schema([
    'query' => $queryType
]);


$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'];
$variableValues = isset($input['variables']) ? $input['variables'] : null;

try {
    $rootValue = ['prefix' => 'prefix: '];
    $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
    $output = $result->toArray();
} catch (\Exception $e) {
    $output = [
        'errors' => [
            [
                'message' => $e->getMessage()
            ]
        ]
    ];
}
header('Content-Type: application/json');
echo json_encode($output);
執(zhí)行示例代碼結(jié)果

PHP中怎么安裝和使用GraphQL

從上面結(jié)果可以看到,我們傳了limit參數(shù)為2,最終從我們模擬的數(shù)據(jù)里面取出了2條數(shù)據(jù)

使用類型語(yǔ)言

在上面的示例中,如果我們代碼返回的數(shù)據(jù)比較復(fù)雜時(shí),需要編寫(xiě)大量的代碼,通過(guò)GraphQL類型語(yǔ)言,我們可以減少代碼量,使代碼看上去更加簡(jiǎn)潔,這是一個(gè)用 GraphQL 類型語(yǔ)言定義的簡(jiǎn)單 Schema示例。

<?php

require_once __DIR__ . '/vendor/autoload.php';
use GraphQL\GraphQL;
use GraphQL\Utils\BuildSchema;
// graph.graphql  文件內(nèi)容
$graph =
<<<GRAPH
schema {
  query: Query
}

type Query {
  graph_test: String
  echo(message: String): String
  show_test: Show
  show_test_arr: [Show]
}


type Show {
    content: String!
    text: String!
}
GRAPH;


$schema = BuildSchema::build($graph);
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'];
$variableValues = isset($input['variables']) ? $input['variables'] : null;

try {
    $rootValue = [
        'sum' => function($rootValue, $args, $context) {
            return $args['x'] + $args['y'];
        },
        'echo' => function($rootValue, $args, $context) {
            return $rootValue['prefix'] . ($args['message'] ?? 'no echo');
        },
        'show_test' => function($rootValue, $args, $context) {
            return [
                'content' => 'show_content',
                'text' => 'xxxx xxx'
            ];
        },
        'show_test_arr' => function($rootValue, $args, $context) {
            return [
                [
                    'content' => 'show_content',
                    'text' => 'xxxx xxx'
                ],
                [
                    'content' => 'show_content_2',
                    'text' => 'xxxx xxx_2'
                ]

            ];
        },
        'prefix' => 'from test:',
        "graph_test" => "graphql_test"
    ];;
    $result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
    $output = $result->toArray();
} catch (\Exception $e) {

    \GraphQL\Server\StandardServer::send500Error($e);
}
header('Content-Type: application/json');
echo json_encode($output);
執(zhí)行示例代碼結(jié)果

PHP中怎么安裝和使用GraphQL

關(guān)于“PHP中怎么安裝和使用GraphQL”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI