Blog

🦸🏿‍♂️ Gato GraphQL est maintenant transpilé de PHP 8.0 à 7.1

Leonardo Losoviz
Par Leonardo Losoviz ·

Il y a quelque temps, j'ai écrit sur l'art de transpiler du code PHP :

Transpiler du code PHP permet d'utiliser les dernières fonctionnalités de PHP pour le développement, tout en publiant le plugin avec son code converti vers une ancienne version de PHP pour la production, afin de cibler une base d'utilisateurs plus large.

J'ai passé les dernières semaines à affiner davantage ce processus pour le plugin Gato GraphQL.

Je suis heureux d'annoncer que, désormais, la version PHP requise a été mise à niveau vers PHP 8.0 :

Mise à niveau vers la version PHP minimale 8.0

Comme le plugin peut désormais compter sur PHP 8.0, j'ai pu terminer l'ajout d'un type à toutes les propriétés pour toutes les classes PHP dans l'ensemble du code, en incluant maintenant également les union types.

Formidable !

Voici le résumé de toutes les nouvelles fonctionnalités de PHP 8.0 disponibles lors du développement du plugin.

Nouvelles fonctionnalités de PHP 8.0

Lors du développement de Gato GraphQL, les fonctionnalités PHP 8.0 suivantes sont désormais disponibles :

Voyons un exemple de chacune, comment elles sont utilisées dans le plugin pour le développement, et en quoi elles sont transpilées lors de la génération de graphql-api.zip.

Union types

Exemple de code :

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

Transpilé en :

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

Pseudo-type mixed

Exemple de code :

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

Transpilé en :

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

Constante magique ::class sur les objets

Exemple de code :

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

Transpilé en :

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

Expressions match

Exemple de code :

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

Transpilé en :

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 exceptions par type uniquement

Exemple de code :

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

Transpilé en :

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

Opérateur Null-safe

Exemple de code :

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

Transpilé en :

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

Promotion des propriétés dans le constructeur de classe

Exemple de code :

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

Transpilé en :

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

Virgules de fin dans les listes de paramètres et les listes use de closures

Exemple de code :

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

Transpilé en :

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

Abonnez-vous à notre newsletter

Restez au courant de toutes les nouveautés de Gato GraphQL.