src/Utils/AST.php
public static function astFromValue($value, InputType $type)
    {
        if ($type instanceof NonNull) {
            $astValue = self::astFromValue($value, $type->getWrappedType());
            if ($astValue instanceof NullValueNode) {
                return null;
            }

            return $astValue;
        }

        if ($value === null) {
            return new NullValueNode([]);
        }

        // Convert PHP array to GraphQL list. If the GraphQLType is a list, but
        // the value is not an array, convert the value using the list's item type.
        if ($type instanceof ListOfType) {
            $itemType = $type->getWrappedType();
            if (is_array($value) || ($value instanceof Traversable)) {
                $valuesNodes = [];
                foreach ($value as $item) {
                    $itemNode = self::astFromValue($item, $itemType);
                    if (! $itemNode) {
                        continue;
                    }

                    $valuesNodes[] = $itemNode;
                }

                return new ListValueNode(['values' => $valuesNodes]);
            }

            return self::astFromValue($value, $itemType);
        }

        // Populate the fields of the input object by creating ASTs from each value
        // in the PHP object according to the fields in the input type.
        if ($type instanceof InputObjectType) {
            $isArray     = is_array($value);
            $isArrayLike = $isArray || $value instanceof ArrayAccess;
            if ($value === null || (! $isArrayLike && ! is_object($value))) {
                return null;
            }
            $fields     = $type->getFields();
            $fieldNodes = [];
            foreach ($fields as $fieldName => $field) {
                if ($isArrayLike) {
                    $fieldValue = $value[$fieldName] ?? null;
                } else {
                    $fieldValue = $value->{$fieldName} ?? null;
                }

                // Have to check additionally if key exists, since we differentiate between
                // "no key" and "value is null":
                if ($fieldValue !== null) {
                    $fieldExists = true;
                } elseif ($isArray) {
                    $fieldExists = array_key_exists($fieldName, $value);
                } elseif ($isArrayLike) {
                    /** @var ArrayAccess $value */
                    $fieldExists = $value->offsetExists($fieldName);
                } else {
                    $fieldExists = property_exists($value, $fieldName);
                }

                if (! $fieldExists) {
                    continue;
                }

                $fieldNode = self::astFromValue($fieldValue, $field->getType());

                if (! $fieldNode) {
                    continue;
                }

                $fieldNodes[] = new ObjectFieldNode([
                    'name'  => new NameNode(['value' => $fieldName]),
                    'value' => $fieldNode,
                ]);
            }

            return new ObjectValueNode(['fields' => $fieldNodes]);
        }

        if ($type instanceof ScalarType || $type instanceof EnumType) {
            // Since value is an internally represented value, it must be serialized
            // to an externally represented value before converting into an AST.
            try {
                $serialized = $type->serialize($value);
            } catch (Exception $error) {
                if ($error instanceof Error && $type instanceof EnumType) {
                    return null;
                }
                throw $error;
            } catch (Throwable $error) {
                if ($error instanceof Error && $type instanceof EnumType) {
                    return null;
                }
                throw $error;
            }

            // Others serialize based on their corresponding PHP scalar types.
            if (is_bool($serialized)) {
                return new BooleanValueNode(['value' => $serialized]);
            }
            if (is_int($serialized)) {
                return new IntValueNode(['value' => $serialized]);
            }
            if (is_float($serialized)) {
                // int cast with == used for performance reasons
                // phpcs:ignore
                if ((int) $serialized == $serialized) {
                    return new IntValueNode(['value' => $serialized]);
                }

                return new FloatValueNode(['value' => $serialized]);
            }
            if (is_string($serialized)) {
                // Enum types use Enum literals.
                if ($type instanceof EnumType) {
                    return new EnumValueNode(['value' => $serialized]);
                }

                // ID types can use Int literals.
                $asInt = (int) $serialized;
                if ($type instanceof IDType && (string) $asInt === $serialized) {
                    return new IntValueNode(['value' => $serialized]);
                }

                // Use json_encode, which uses the same string encoding as GraphQL,
                // then remove the quotes.
                return new StringValueNode(['value' => $serialized]);
            }

            throw new InvariantViolation('Cannot convert value to AST: ' . Utils::printSafe($serialized));
        }

        throw new Error('Unknown type: ' . Utils::printSafe($type) . '.');
    }
public static function astFromValue($value, InputType $type)
    {
        if ($type instanceof NonNull) {
            $astValue = self::astFromValue($value, $type->getWrappedType());
            if ($astValue instanceof NullValueNode) {
                return null;
            }

            return $astValue;
        }

        if ($value === null) {
            return new NullValueNode([]);
        }

        // Convert PHP array to GraphQL list. If the GraphQLType is a list, but
        // the value is not an array, convert the value using the list's item type.
        if ($type instanceof ListOfType) {
            $itemType = $type->getWrappedType();
            if (is_array($value) || ($value instanceof Traversable)) {
                $valuesNodes = [];
                foreach ($value as $item) {
                    $itemNode = self::astFromValue($item, $itemType);
                    if (! $itemNode) {
                        continue;
                    }

                    $valuesNodes[] = $itemNode;
                }

                return new ListValueNode(['values' => $valuesNodes]);
            }

            return self::astFromValue($value, $itemType);
        }

        // Populate the fields of the input object by creating ASTs from each value
        // in the PHP object according to the fields in the input type.
        if ($type instanceof InputObjectType) {
            $isArray     = is_array($value);
            $isArrayLike = $isArray || $value instanceof ArrayAccess;
            if ($value === null || (! $isArrayLike && ! is_object($value))) {
                return null;
            }
            $fields     = $type->getFields();
            $fieldNodes = [];
            foreach ($fields as $fieldName => $field) {
                if ($isArrayLike) {
                    $fieldValue = $value[$fieldName] ?? null;
                } else {
                    $fieldValue = $value->{$fieldName} ?? null;
                }

                // Have to check additionally if key exists, since we differentiate between
                // "no key" and "value is null":
                if ($fieldValue !== null) {
                    $fieldExists = true;
                } elseif ($isArray) {
                    $fieldExists = array_key_exists($fieldName, $value);
                } elseif ($isArrayLike) {
                    /** @var ArrayAccess $value */
                    $fieldExists = $value->offsetExists($fieldName);
                } else {
                    $fieldExists = property_exists($value, $fieldName);
                }

                if (! $fieldExists) {
                    continue;
                }

                $fieldNode = self::astFromValue($fieldValue, $field->getType());

                if (! $fieldNode) {
                    continue;
                }

                $fieldNodes[] = new ObjectFieldNode([
                    'name'  => new NameNode(['value' => $fieldName]),
                    'value' => $fieldNode,
                ]);
            }

            return new ObjectValueNode(['fields' => $fieldNodes]);
        }

        if ($type instanceof ScalarType || $type instanceof EnumType) {
            // Since value is an internally represented value, it must be serialized
            // to an externally represented value before converting into an AST.
            try {
                $serialized = $type->serialize($value);
            } catch (Exception $error) {
                if ($error instanceof Error && $type instanceof EnumType) {
                    return null;
                }
                throw $error;
            } catch (Throwable $error) {
                if ($error instanceof Error && $type instanceof EnumType) {
                    return null;
                }
                throw $error;
            }

            // Others serialize based on their corresponding PHP scalar types.
            if (is_bool($serialized)) {
                return new BooleanValueNode(['value' => $serialized]);
            }
            if (is_int($serialized)) {
                return new IntValueNode(['value' => $serialized]);
            }
            if (is_float($serialized)) {
                // int cast with == used for performance reasons
                // phpcs:ignore
                if ((int) $serialized == $serialized) {
                    return new IntValueNode(['value' => $serialized]);
                }

                return new FloatValueNode(['value' => $serialized]);
            }
            if (is_string($serialized)) {
                // Enum types use Enum literals.
                if ($type instanceof EnumType) {
                    return new EnumValueNode(['value' => $serialized]);
                }

                // ID types can use Int literals.
                $asInt = (int) $serialized;
                if ($type instanceof IDType && (string) $asInt === $serialized) {
                    return new IntValueNode(['value' => $serialized]);
                }

                // Use json_encode, which uses the same string encoding as GraphQL,
                // then remove the quotes.
                return new StringValueNode(['value' => $serialized]);
            }

            throw new InvariantViolation('Cannot convert value to AST: ' . Utils::printSafe($serialized));
        }

        throw new Error('Unknown type: ' . Utils::printSafe($type) . '.');
    }
public static function astFromValue ( $ value , InputType $ type ) { if ( $ type instanceof NonNull ) { $ astValue = self :: astFromValue ( $ value , $ type -> getWrappedType ( ) ) ; if ( $ astValue instanceof NullValueNode ) { return null ; } return $ astValue ; } if ( $ value === null ) { return new NullValueNode ( [ ] ) ; } // Convert PHP array to GraphQL list. If the GraphQLType is a list, but // the value is not an array, convert the value using the list's item type. if ( $ type instanceof ListOfType ) { $ itemType = $ type -> getWrappedType ( ) ; if ( is_array ( $ value ) || ( $ value instanceof Traversable ) ) { $ valuesNodes = [ ] ; foreach ( $ value as $ item ) { $ itemNode = self :: astFromValue ( $ item , $ itemType ) ; if ( ! $ itemNode ) { continue ; } $ valuesNodes [ ] = $ itemNode ; } return new ListValueNode ( [ 'values' => $ valuesNodes ] ) ; } return self :: astFromValue ( $ value , $ itemType ) ; } // Populate the fields of the input object by creating ASTs from each value // in the PHP object according to the fields in the input type. if ( $ type instanceof InputObjectType ) { $ isArray = is_array ( $ value ) ; $ isArrayLike = $ isArray || $ value instanceof ArrayAccess ; if ( $ value === null || ( ! $ isArrayLike && ! is_object ( $ value ) ) ) { return null ; } $ fields = $ type -> getFields ( ) ; $ fieldNodes = [ ] ; foreach ( $ fields as $ fieldName => $ field ) { if ( $ isArrayLike ) { $ fieldValue = $ value [ $ fieldName ] ?? null ; } else { $ fieldValue = $ value -> { $ fieldName } ?? null ; } // Have to check additionally if key exists, since we differentiate between // "no key" and "value is null": if ( $ fieldValue !== null ) { $ fieldExists = true ; } elseif ( $ isArray ) { $ fieldExists = array_key_exists ( $ fieldName , $ value ) ; } elseif ( $ isArrayLike ) { /** @var ArrayAccess $value */ $ fieldExists = $ value -> offsetExists ( $ fieldName ) ; } else { $ fieldExists = property_exists ( $ value , $ fieldName ) ; } if ( ! $ fieldExists ) { continue ; } $ fieldNode = self :: astFromValue ( $ fieldValue , $ field -> getType ( ) ) ; if ( ! $ fieldNode ) { continue ; } $ fieldNodes [ ] = new ObjectFieldNode ( [ 'name' => new NameNode ( [ 'value' => $ fieldName ] ) , 'value' => $ fieldNode , ] ) ; } return new ObjectValueNode ( [ 'fields' => $ fieldNodes ] ) ; } if ( $ type instanceof ScalarType || $ type instanceof EnumType ) { // Since value is an internally represented value, it must be serialized // to an externally represented value before converting into an AST. try { $ serialized = $ type -> serialize ( $ value ) ; } catch ( Exception $ error ) { if ( $ error instanceof Error && $ type instanceof EnumType ) { return null ; } throw $ error ; } catch ( Throwable $ error ) { if ( $ error instanceof Error && $ type instanceof EnumType ) { return null ; } throw $ error ; } // Others serialize based on their corresponding PHP scalar types. if ( is_bool ( $ serialized ) ) { return new BooleanValueNode ( [ 'value' => $ serialized ] ) ; } if ( is_int ( $ serialized ) ) { return new IntValueNode ( [ 'value' => $ serialized ] ) ; } if ( is_float ( $ serialized ) ) { // int cast with == used for performance reasons // phpcs:ignore if ( ( int ) $ serialized == $ serialized ) { return new IntValueNode ( [ 'value' => $ serialized ] ) ; } return new FloatValueNode ( [ 'value' => $ serialized ] ) ; } if ( is_string ( $ serialized ) ) { // Enum types use Enum literals. if ( $ type instanceof EnumType ) { return new EnumValueNode ( [ 'value' => $ serialized ] ) ; } // ID types can use Int literals. $ asInt = ( int ) $ serialized ; if ( $ type instanceof IDType && ( string ) $ asInt === $ serialized ) { return new IntValueNode ( [ 'value' => $ serialized ] ) ; } // Use json_encode, which uses the same string encoding as GraphQL, // then remove the quotes. return new StringValueNode ( [ 'value' => $ serialized ] ) ; } throw new InvariantViolation ( 'Cannot convert value to AST: ' . Utils :: printSafe ( $ serialized ) ) ; } throw new Error ( 'Unknown type: ' . Utils :: printSafe ( $ type ) . '.' ) ; }
Produces a GraphQL Value AST given a PHP value.

Optionally, a GraphQL type may be provided, which will be used to
disambiguate between value primitives.

| PHP Value     | GraphQL Value        |
| ------------- | -------------------- |
| Object        | Input Object         |
| Assoc Array   | Input Object         |
| Array         | List                 |
| Boolean       | Boolean              |
| String        | String / Enum Value  |
| Int           | Int                  |
| Float         | Int / Float          |
| Mixed         | Enum Value           |
| null          | NullValue            |

@param Type|mixed|null $value

@return ObjectValueNode|ListValueNode|BooleanValueNode|IntValueNode|FloatValueNode|EnumValueNode|StringValueNode|NullValueNode

@api
Produces a GraphQL Value AST given a PHP value .