🦸🏿♂️ Gato GraphQL jest teraz transpilowany z PHP 8.0 do 7.1
Jakiś czas temu napisałem o sztuce transpilowania kodu 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
Transpilowanie kodu PHP pozwala korzystać z najnowszych funkcji PHP podczas programowania, a jednocześnie publikować wtyczkę z kodem przekonwertowanym do starszej wersji PHP na potrzeby produkcji, aby dotrzeć do szerszej bazy użytkowników.
Przez ostatnie kilka tygodni dalej dopracowywałem ten proces dla wtyczki Gato GraphQL.
Z przyjemnością ogłaszam, że od teraz wymagana minimalna wersja PHP została zaktualizowana do PHP 8.0:

Ponieważ wtyczka może teraz polegać na PHP 8.0, udało mi się ukończyć dodawanie typów do wszystkich właściwości we wszystkich klasach PHP w całej bazie kodu, włącznie z union types.
Wspaniale!
Oto podsumowanie wszystkich nowych funkcji PHP 8.0 dostępnych podczas tworzenia wtyczki.
Nowe funkcje PHP 8.0
Podczas tworzenia Gato GraphQL dostępne są teraz następujące funkcje PHP 8.0:
- Union types
- Pseudotyp
mixed - Typ zwracany
static - Stała magiczna
::classna obiektach - Wyrażenia
match catchwyjątków tylko po typie- Operator Null-safe
- Promocja właściwości w konstruktorze klasy
- Końcowe przecinki w listach parametrów i listach
usedomknięć
Zobaczmy przykład każdej z nich — jak są używane we wtyczce podczas programowania i do czego są transpilowane podczas generowania graphql-api.zip.
Union types
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data): string | int | null | Error;
}Transpilowane do:
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data)
}Pseudotyp mixed
interface CMSServiceInterface
{
public function getOption(string $option, mixed $default = false): mixed;
}Transpilowane do:
interface CMSServiceInterface
{
public function getOption(string $option, $default = false);
}Stała magiczna ::class na obiektach
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = $directiveResolver::class;
}Transpilowane do:
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = get_class($directiveResolver);
}Wyrażenia 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;
}Transpilowane do:
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 wyjątków tylko po typie
try {
// ...
} catch (InvalidArgumentException) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Transpilowane do:
try {
// ...
} catch (InvalidArgumentException $exception) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Operator Null-safe
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver)?->getSchemaDirectiveDeprecationDescription($typeResolver);
}Transpilowane do:
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver) ? $this->getSchemaDefinitionResolver($typeResolver)->getSchemaDirectiveDeprecationDescription($typeResolver) : null;
}Promocja właściwości w konstruktorze klasy
abstract class AbstractEndpointResolver
{
function __construct(protected EndpointHelpers $endpointHelpers)
{
}
}Transpilowane do:
abstract class AbstractEndpointResolver
{
/**
* @var \GraphQLAPI\GraphQLAPI\Services\Helpers\EndpointHelpers
*/
protected $endpointHelpers;
function __construct(EndpointHelpers $endpointHelpers)
{
$this->endpointHelpers = $endpointHelpers;
}
}Końcowe przecinki w listach parametrów i listach use domknięć
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass(
$typeResolver,
$fieldName,
);
}Transpilowane do:
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass($typeResolver, $fieldName);
}