🦸🏿♂️ Gato GraphQL ora viene transpilato da PHP 8.0 a 7.1
Qualche tempo fa ho scritto sull'arte di transpilare il codice PHP:
- 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
Transpilare il codice PHP permette di usare le ultime funzionalità di PHP per lo sviluppo, pur pubblicando il plugin con il suo codice convertito a una versione precedente di PHP per la produzione, così da rivolgersi a una base di utenti più ampia.
Ho passato le ultime settimane a perfezionare ulteriormente questo processo per il plugin Gato GraphQL.
Sono felice di annunciare che, d'ora in poi, la versione di PHP richiesta è stata aggiornata a PHP 8.0:

Dato che il plugin ora può contare su PHP 8.0, sono riuscito a completare l'aggiunta di un tipo a tutte le proprietà per tutte le classi PHP in tutto il codice, includendo ora anche gli union types.
Fantastico!
Ecco il riepilogo di tutte le nuove funzionalità di PHP 8.0 disponibili durante lo sviluppo del plugin.
Nuove funzionalità di PHP 8.0
Durante lo sviluppo di Gato GraphQL, le seguenti funzionalità di PHP 8.0 sono ora disponibili:
- Union types
- Pseudo-tipo
mixed - Tipo di ritorno
static - Costante magica
::classsugli oggetti - Espressioni
match catchdelle eccezioni solo per tipo- Operatore Null-safe
- Promozione delle proprietà nel costruttore di classe
- Virgole finali nelle liste di parametri e nelle liste
usedelle closure
Vediamo un esempio di ciascuna, come vengono usate nel plugin per lo sviluppo e in cosa vengono transpilate durante la generazione di graphql-api.zip.
Union types
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data): string | int | null | Error;
}Transpilato in:
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data)
}Pseudo-tipo mixed
interface CMSServiceInterface
{
public function getOption(string $option, mixed $default = false): mixed;
}Transpilato in:
interface CMSServiceInterface
{
public function getOption(string $option, $default = false);
}Costante magica ::class sugli oggetti
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = $directiveResolver::class;
}Transpilato in:
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = get_class($directiveResolver);
}Espressioni match
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;
}Transpilato in:
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 delle eccezioni solo per tipo
try {
// ...
} catch (InvalidArgumentException) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Transpilato in:
try {
// ...
} catch (InvalidArgumentException $exception) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Operatore Null-safe
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver)?->getSchemaDirectiveDeprecationDescription($typeResolver);
}Transpilato in:
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver) ? $this->getSchemaDefinitionResolver($typeResolver)->getSchemaDirectiveDeprecationDescription($typeResolver) : null;
}Promozione delle proprietà nel costruttore di classe
abstract class AbstractEndpointResolver
{
function __construct(protected EndpointHelpers $endpointHelpers)
{
}
}Transpilato in:
abstract class AbstractEndpointResolver
{
/**
* @var \GraphQLAPI\GraphQLAPI\Services\Helpers\EndpointHelpers
*/
protected $endpointHelpers;
function __construct(EndpointHelpers $endpointHelpers)
{
$this->endpointHelpers = $endpointHelpers;
}
}Virgole finali nelle liste di parametri e nelle liste use delle closure
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass(
$typeResolver,
$fieldName,
);
}Transpilato in:
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass($typeResolver, $fieldName);
}