Π‘Π»ΠΎΠ³

πŸ¦ΈπŸΏβ€β™‚οΈ Gato GraphQL Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ транспилируСтся с PHP 8.0 Π΄ΠΎ 7.1

Leonardo Losoviz
Автор: Leonardo Losoviz Β·

НСкотороС врСмя Π½Π°Π·Π°Π΄ я написал ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ транспиляция PHP-ΠΊΠΎΠ΄Π°:

Вранспиляция PHP-ΠΊΠΎΠ΄Π° позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ новСйшиС возмоТности PHP ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅, Π½ΠΎ Π²Ρ‹ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΠ»Π°Π³ΠΈΠ½ с ΠΊΠΎΠ΄ΠΎΠΌ, ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π² Π±ΠΎΠ»Π΅Π΅ ΡΡ‚Π°Ρ€ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ PHP для ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΡˆΠΈΡ€ΠΎΠΊΡƒΡŽ Π°ΡƒΠ΄ΠΈΡ‚ΠΎΡ€ΠΈΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

ПослСдниС нСсколько нСдСль я занимался дальнСйшСй Π΄ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ этого процСсса для ΠΏΠ»Π°Π³ΠΈΠ½Π° Gato GraphQL.

Π Π°Π΄ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΡ‚Π½Ρ‹Π½Π΅ минимально трСбуСмая вСрсия PHP Π±Ρ‹Π»Π° ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½Π° Π΄ΠΎ PHP 8.0:

ОбновлСниС Π΄ΠΎ минимальной вСрсии PHP 8.0

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠ»Π°Π³ΠΈΠ½ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° PHP 8.0, ΠΌΠ½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² ΠΊΠΎ всСм свойствам Π²ΠΎ всСх PHP-классах ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Ρ‹, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ union types.

ΠŸΡ€Π΅Π²ΠΎΡΡ…ΠΎΠ΄Π½ΠΎ!

Π’ΠΎΡ‚ ΠΊΡ€Π°Ρ‚ΠΊΠΎΠ΅ описаниС всСх Π½ΠΎΠ²Ρ‹Ρ… возмоТностСй PHP 8.0, доступных ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½Π°.

НовыС возмоТности PHP 8.0

ΠŸΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Gato GraphQL Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ доступны ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ возмоТности PHP 8.0:

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· Π½ΠΈΡ…: ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² ΠΏΠ»Π°Π³ΠΈΠ½Π΅ ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΈ Π²ΠΎ Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π°Π½ΡΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ graphql-api.zip.

Union types

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

interface CustomPostTypeAPIInterface
{
  public function createCustomPost(array $data): string | int | null | Error;
}

ВранспилируСтся Π²:

interface CustomPostTypeAPIInterface
{
  public function createCustomPost(array $data)
}

ΠŸΡΠ΅Π²Π΄ΠΎΡ‚ΠΈΠΏ mixed

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

interface CMSServiceInterface
{
  public function getOption(string $option, mixed $default = false): mixed;
}

ВранспилируСтся Π²:

interface CMSServiceInterface
{
  public function getOption(string $option, $default = false);
}

ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠ°Ρ константа ::class Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ…

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

foreach ($directiveResolvers as $directiveResolver) {
  $directiveResolverName = $directiveResolver->getDirectiveName();
  $this->directiveNameClasses[$directiveResolverName][] = $directiveResolver::class;
}

ВранспилируСтся Π²:

foreach ($directiveResolvers as $directiveResolver) {
  $directiveResolverName = $directiveResolver->getDirectiveName();
  $this->directiveNameClasses[$directiveResolverName][] = get_class($directiveResolver);
}

ВыраТСния match

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

public function getSchemaFieldType(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
  $ret = match($fieldName) {
    'accessControlLists' => TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID),
    'cacheControlLists' => TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID),
    'fieldDeprecationLists' => TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID),
    'schemaConfigurations' => TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID),
    default => parent::getSchemaFieldType($typeResolver, $fieldName),
  };
  return $ret;
}

ВранспилируСтся Π²:

public function getSchemaFieldType(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
  switch ($fieldName) {
    case 'accessControlLists':
      $ret = TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID);
      break;
    case 'cacheControlLists':
      $ret = TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID);
      break;
    case 'fieldDeprecationLists':
      $ret = TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID);
      break;
    case 'schemaConfigurations':
      $ret = TypeCastingHelpers::makeArray(SchemaDefinition::TYPE_ID);
      break;
    default:
      $ret = parent::getSchemaFieldType($typeResolver, $fieldName);
      break;
  }
  return $ret;
}

catch ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

try {
  // ...
} catch (InvalidArgumentException) {
  return sprintf(
    '<p>%s</p>',
    \__('Oops, the documentation for this module is not available', 'graphql-api')
  );
}

ВранспилируСтся Π²:

try {
  // ...
} catch (InvalidArgumentException $exception) {
  return sprintf(
    '<p>%s</p>',
    \__('Oops, the documentation for this module is not available', 'graphql-api')
  );
}

Null-safe ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
  return $this->getSchemaDefinitionResolver($typeResolver)?->getSchemaDirectiveDeprecationDescription($typeResolver);
}

ВранспилируСтся Π²:

public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
  return $this->getSchemaDefinitionResolver($typeResolver) ? $this->getSchemaDefinitionResolver($typeResolver)->getSchemaDirectiveDeprecationDescription($typeResolver) : null;
}

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ свойств Π² конструкторС класса

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

abstract class AbstractEndpointResolver
{
  function __construct(protected EndpointHelpers $endpointHelpers)
  {
  }
}

ВранспилируСтся Π²:

 abstract class AbstractEndpointResolver
 {
  /**
   * @var \GraphQLAPI\GraphQLAPI\Services\Helpers\EndpointHelpers
   */
  protected $endpointHelpers;
 
  function __construct(EndpointHelpers $endpointHelpers)
  {
    $this->endpointHelpers = $endpointHelpers;
  }
}

Π—Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠ΅ запятыС Π² списках ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈ списках use Π² замыканиях

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°:

public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
    switch ($fieldName) {
        case 'accessControlLists':
            return CustomPostTypeResolver::class;
    }
 
    return parent::resolveFieldTypeResolverClass(
        $typeResolver,
        $fieldName,
    );
}

ВранспилируСтся Π²:

public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
    switch ($fieldName) {
        case 'accessControlLists':
            return CustomPostTypeResolver::class;
    }
 
    return parent::resolveFieldTypeResolverClass($typeResolver, $fieldName);
}

ΠŸΠΎΠ΄ΠΏΠΈΡˆΠΈΡ‚Π΅ΡΡŒ Π½Π° Π½Π°ΡˆΡƒ рассылку

Π‘ΡƒΠ΄ΡŒΡ‚Π΅ Π² курсС всСх ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ Gato GraphQL.