
<a name="query-complexity-analysis"></a>
# 查询的复杂性分析

这是一个在 Sangria 实现中的  [查询复杂性分析](http://sangria-graphql.org/learn/#query-complexity-analysis) 的 PHP 接口

复杂性分析是一种在执行之前计算查询复杂性分数的独立验证规则。
在查询中的每一个字段都有一个默认的分数为 1  （包括 ObjectType 节点 ）。总的查询的复杂度是由每个字段的分数组成。 例如， 内省查询的复杂度是 **109**。

如果这个分数查过了临界值，那么该查询并不会执行而是会返回一个错误。

在默认情况下，复杂性分析是被禁用的，如果要启用，则要添加如下规则：
```php
<?php
use GraphQL\GraphQL;
use GraphQL\Validator\Rules\QueryComplexity;
use GraphQL\Validator\DocumentValidator;

$rule = new QueryComplexity($maxQueryComplexity = 100);
DocumentValidator::addRule($rule);

GraphQL::executeQuery(/*...*/);
```
这将在全局设置规则。 或者，你也可以为 [每次执行](${doc_url}/executing-queries#custom-validation-rules) 提供验证规则。

要自定义字段的分数，添加  **复杂性** 函数到你的自定义中：
```php
<?php
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ObjectType;

$type = new ObjectType([
    'name' => 'MyType',
    'fields' => [
        'someList' => [
            'type' => Type::listOf(Type::string()),
            'args' => [
                'limit' => [
                    'type' => Type::int(),
                    'defaultValue' => 10
                ]
            ],
            'complexity' => function($childrenComplexity, $args) {
                return $childrenComplexity * $args['limit'];
            }
        ]
    ]
]);
```


# 限制查询深度

这是 Sangria 执行中 [限制查询深度](http://sangria-graphql.org/learn/#limiting-query-depth) 的 PHP 端口。
例如，内部查询的最大深度为 **7**.

该配置默认是禁用的。你可以添加下面的验证规则来启用它：

```php
<?php
use GraphQL\GraphQL;
use GraphQL\Validator\Rules\QueryDepth;
use GraphQL\Validator\DocumentValidator;

$rule = new QueryDepth($maxDepth = 10);
DocumentValidator::addRule($rule);

GraphQL::executeQuery(/*...*/);
```

这将是全局的规则。或者，你可以 [每个查询过程](${doc_url}/executing-queries#custom-validation-rules) 都提供一个验证规则。


# 禁用自省
[自省](http://graphql.org/learn/introspection/)  是一种获取模式结构的机制。
它被用做像  GraphiQL 的自动补全，查询验证等的工具。

内省是默认开启的。那就意味着任何一个人可以通过发送一个包含     **__type**  和 **__schema**  的元字段的特殊查询就可以获取到你的模式的完整描述。

如果你不打算对大众公开你的 API ，那么禁用这个属性是非常有必要的。

GraphQL PHP 为你提供单独的验证规则，该规则禁止查询包含有 
**__type**  或者 **__schema**  字段。如果要禁用自省，请添加如下的规则： 

```php
<?php
use GraphQL\GraphQL;
use GraphQL\Validator\Rules\DisableIntrospection;
use GraphQL\Validator\DocumentValidator;

DocumentValidator::addRule(new DisableIntrospection());

GraphQL::executeQuery(/*...*/);
```
这将会在全局制定规则。或者，你也可以为 [每次执行](${doc_url}/executing-queries#custom-validation-rules) 提供验证规则。