Blog

🦸🏿‍♂️ Gato GraphQL wird jetzt von PHP 8.0 auf 7.1 transpiliert

Leonardo Losoviz
Von Leonardo Losoviz ·

Vor einiger Zeit habe ich über die Kunst des Transpilierens von PHP-Code geschrieben:

Das Transpilieren von PHP-Code ermöglicht es, die neuesten PHP-Funktionen für die Entwicklung zu nutzen und das Plugin dennoch mit auf eine ältere PHP-Version konvertiertem Code für die Produktion zu veröffentlichen, um eine größere Nutzerbasis anzusprechen.

Ich habe die letzten Wochen damit verbracht, diesen Prozess für das Plugin Gato GraphQL weiter zu verfeinern.

Ich freue mich, ankündigen zu können, dass die erforderliche PHP-Version ab sofort auf PHP 8.0 angehoben wurde:

Upgrade auf die minimale PHP-Version 8.0

Da das Plugin nun auf PHP 8.0 zählen kann, konnte ich das Hinzufügen eines Typs zu allen Eigenschaften für alle PHP-Klassen im gesamten Codebase abschließen, einschließlich Union Types.

Großartig!

Hier ist die Zusammenfassung aller neuen PHP-8.0-Funktionen, die bei der Entwicklung des Plugins verfügbar sind.

Neue PHP-8.0-Funktionen

Bei der Entwicklung von Gato GraphQL stehen jetzt folgende PHP-8.0-Funktionen zur Verfügung:

Sehen wir uns jeweils ein Beispiel an, wie sie im Plugin für die Entwicklung verwendet werden und wohin sie beim Generieren von graphql-api.zip transpiliert werden.

Union types

Codebeispiel:

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

Transpiliert zu:

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

Pseudo-Typ mixed

Codebeispiel:

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

Transpiliert zu:

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

Magische Konstante ::class auf Objekten

Codebeispiel:

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

Transpiliert zu:

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

match-Ausdrücke

Codebeispiel:

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

Transpiliert zu:

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-Ausnahmen nur nach Typ

Codebeispiel:

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

Transpiliert zu:

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

Null-safe-Operator

Codebeispiel:

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

Transpiliert zu:

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

Promotion von Klassen-Konstruktor-Eigenschaften

Codebeispiel:

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

Transpiliert zu:

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

Abschließende Kommas in Parameterlisten und use-Listen von Closures

Codebeispiel:

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

Transpiliert zu:

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

Abonniere unseren Newsletter

Bleib über alle Updates zu Gato GraphQL auf dem Laufenden.