Blog

🦸🏿‍♂️ Gato GraphQL jest teraz transpilowany z PHP 8.0 do 7.1

Leonardo Losoviz
Autor: Leonardo Losoviz ·

Jakiś czas temu napisałem o sztuce transpilowania kodu PHP:

Transpilowanie kodu PHP pozwala korzystać z najnowszych funkcji PHP podczas programowania, a jednocześnie publikować wtyczkę z kodem przekonwertowanym do starszej wersji PHP na potrzeby produkcji, aby dotrzeć do szerszej bazy użytkowników.

Przez ostatnie kilka tygodni dalej dopracowywałem ten proces dla wtyczki Gato GraphQL.

Z przyjemnością ogłaszam, że od teraz wymagana minimalna wersja PHP została zaktualizowana do PHP 8.0:

Aktualizacja do minimalnej wersji PHP 8.0

Ponieważ wtyczka może teraz polegać na PHP 8.0, udało mi się ukończyć dodawanie typów do wszystkich właściwości we wszystkich klasach PHP w całej bazie kodu, włącznie z union types.

Wspaniale!

Oto podsumowanie wszystkich nowych funkcji PHP 8.0 dostępnych podczas tworzenia wtyczki.

Nowe funkcje PHP 8.0

Podczas tworzenia Gato GraphQL dostępne są teraz następujące funkcje PHP 8.0:

Zobaczmy przykład każdej z nich — jak są używane we wtyczce podczas programowania i do czego są transpilowane podczas generowania graphql-api.zip.

Union types

Przykład kodu:

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

Transpilowane do:

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

Pseudotyp mixed

Przykład kodu:

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

Transpilowane do:

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

Stała magiczna ::class na obiektach

Przykład kodu:

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

Transpilowane do:

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

Wyrażenia match

Przykład kodu:

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;
}

Transpilowane do:

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 wyjątków tylko po typie

Przykład kodu:

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

Transpilowane do:

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

Operator Null-safe

Przykład kodu:

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

Transpilowane do:

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

Promocja właściwości w konstruktorze klasy

Przykład kodu:

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

Transpilowane do:

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

Końcowe przecinki w listach parametrów i listach use domknięć

Przykład kodu:

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

Transpilowane do:

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

Zapisz się do naszego newslettera

Bądź na bieżąco ze wszystkimi aktualizacjami Gato GraphQL.