π¦ΈπΏββοΈ Gato GraphQL wordt nu getranspileerd van PHP 8.0 naar 7.1
Enige tijd geleden schreef ik over de kunst van het transpileren van PHP-code:
- Transpiling PHP code from 8.0 to 7.x via Rector
- Coding in PHP 7.4 and deploying to 7.1 via Rector and GitHub Actions
Het transpileren van PHP-code maakt het mogelijk om de nieuwste PHP-functies te gebruiken tijdens de ontwikkeling, maar de plugin te publiceren met code die geconverteerd is naar een oudere PHP-versie voor productie, zodat je een groter gebruikersbestand bereikt.
De afgelopen weken heb ik dit proces verder verfijnd voor de Gato GraphQL plugin.
Ik ben blij te kunnen aankondigen dat de vereiste minimale PHP-versie vanaf nu is bijgewerkt naar PHP 8.0:

Omdat de plugin nu kan rekenen op PHP 8.0, heb ik het toevoegen van een type aan alle eigenschappen voor alle PHP-klassen in de codebase kunnen voltooien, inclusief union types.
Geweldig!
Hier is een overzicht van alle nieuwe PHP 8.0-functies die beschikbaar zijn bij het ontwikkelen van de plugin.
Nieuwe PHP 8.0-functies
Bij het ontwikkelen van Gato GraphQL zijn de volgende PHP 8.0-functies nu beschikbaar:
- Union types
- Pseudo-type
mixed - Returntype
static - Magische constante
::classop objecten match-expressiescatch-uitzonderingen alleen op type- Null-safe operator
- Property promotion in klasseconstructor
- Afsluitende komma's in parameterlijsten en
use-lijsten van closures
Laten we een voorbeeld bekijken van elk, hoe ze worden gebruikt in de plugin tijdens de ontwikkeling, en waarnaar ze worden getranspileerd bij het genereren van graphql-api.zip.
Union types
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data): string | int | null | Error;
}Getranspileerd naar:
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data)
}Pseudo-type mixed
interface CMSServiceInterface
{
public function getOption(string $option, mixed $default = false): mixed;
}Getranspileerd naar:
interface CMSServiceInterface
{
public function getOption(string $option, $default = false);
}Magische constante ::class op objecten
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = $directiveResolver::class;
}Getranspileerd naar:
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = get_class($directiveResolver);
}match-expressies
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;
}Getranspileerd naar:
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-uitzonderingen alleen op type
try {
// ...
} catch (InvalidArgumentException) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Getranspileerd naar:
try {
// ...
} catch (InvalidArgumentException $exception) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Null-safe operator
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver)?->getSchemaDirectiveDeprecationDescription($typeResolver);
}Getranspileerd naar:
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver) ? $this->getSchemaDefinitionResolver($typeResolver)->getSchemaDirectiveDeprecationDescription($typeResolver) : null;
}Property promotion in klasseconstructor
abstract class AbstractEndpointResolver
{
function __construct(protected EndpointHelpers $endpointHelpers)
{
}
}Getranspileerd naar:
abstract class AbstractEndpointResolver
{
/**
* @var \GraphQLAPI\GraphQLAPI\Services\Helpers\EndpointHelpers
*/
protected $endpointHelpers;
function __construct(EndpointHelpers $endpointHelpers)
{
$this->endpointHelpers = $endpointHelpers;
}
}Afsluitende komma's in parameterlijsten en use-lijsten van closures
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass(
$typeResolver,
$fieldName,
);
}Getranspileerd naar:
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass($typeResolver, $fieldName);
}