Blog

🦸🏿‍♂️ Gato GraphQL ahora se transpila de PHP 8.0 a 7.1

Leonardo Losoviz
Por Leonardo Losoviz ·

Hace algún tiempo, escribí sobre el arte de transpilar código PHP:

Transpilar código PHP permite usar las últimas características de PHP para desarrollo, pero lanzar el plugin con su código convertido a una versión más antigua de PHP para producción, para apuntar a una base de usuarios más grande.

He pasado las últimas semanas afinando aún más este proceso para el plugin Gato GraphQL.

Estoy contento de anunciar que, a partir de ahora, su versión requerida de PHP ha sido actualizada, a PHP 8.0:

Actualizando a versión mínima de PHP 8.0

Como el plugin ahora puede contar con PHP 8.0, he podido completar la adición de un tipo a todas las propiedades para todas las clases PHP a lo largo del código base, incluyendo ahora también los union types.

¡Genial!

Aquí está el resumen de todas las nuevas características de PHP 8.0 disponibles al desarrollar el plugin.

Nuevas características de PHP 8.0

Al desarrollar Gato GraphQL, las siguientes características de PHP 8.0 están ahora disponibles:

Veamos un ejemplo de cada una, cómo se usan en el plugin para desarrollo, y a qué se transpilan al generar graphql-api.zip.

Union types

Código de ejemplo:

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

Transpilado a:

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

Pseudo tipo mixed

Código de ejemplo:

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

Transpilado a:

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

Constante mágica ::class en objetos

Código de ejemplo:

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

Transpilado a:

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

Expresiones match

Código de ejemplo:

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

Transpilado a:

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 excepciones solo por tipo

Código de ejemplo:

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

Transpilado a:

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

Operador Null-safe

Código de ejemplo:

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

Transpilado a:

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

Promoción de propiedades en el constructor de clase

Código de ejemplo:

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

Transpilado a:

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

Comas finales en listas de parámetros y listas use de closures

Código de ejemplo:

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

Transpilado a:

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

Suscríbete a nuestra newsletter

Mantente al tanto de todas las novedades de Gato GraphQL.