🦸🏿♂️ Gato GraphQL ได้รับการ transpile จาก PHP 8.0 เป็น 7.1 แล้ว
เมื่อไม่นานมานี้ ฉันได้เขียนเกี่ยวกับศิลปะของการ transpile โค้ด 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
การ transpile โค้ด PHP ช่วยให้สามารถใช้คุณสมบัติ PHP ล่าสุดในการพัฒนา แต่ยังสามารถเผยแพร่ปลั๊กอินพร้อมโค้ดที่แปลงเป็น PHP เวอร์ชันเก่าสำหรับ production เพื่อรองรับฐานผู้ใช้ที่กว้างขึ้น
ฉันใช้เวลาหลายสัปดาห์ที่ผ่านมาในการปรับแต่งกระบวนการนี้เพิ่มเติมสำหรับปลั๊กอิน Gato GraphQL
ฉันยินดีประกาศว่า ตั้งแต่บัดนี้เป็นต้นไป เวอร์ชัน PHP ที่ต้องการได้รับการอัปเกรดเป็น PHP 8.0 แล้ว:

เนื่องจากปลั๊กอินสามารถพึ่งพา PHP 8.0 ได้แล้ว ฉันจึงสามารถทำการเพิ่ม type ให้กับ properties ทั้งหมดของทุก PHP class ในโค้ดเบสได้สำเร็จ รวมถึง union types ด้วย
ยอดเยี่ยมมาก!
นี่คือสรุปคุณสมบัติใหม่ทั้งหมดของ PHP 8.0 ที่มีให้ใช้งานในการพัฒนาปลั๊กอิน
คุณสมบัติใหม่ของ PHP 8.0
เมื่อพัฒนา Gato GraphQL คุณสมบัติ PHP 8.0 ต่อไปนี้พร้อมใช้งานแล้ว:
- Union types
- pseudo type
mixed - return type
static - magic constant
::classบน objects - expressions
match - การ
catchexceptions เฉพาะตาม type - Null-safe operator
- Class constructor property promotion
- Trailing commas ในรายการ parameters และรายการ
useของ closure
มาดูตัวอย่างของแต่ละรายการ วิธีที่ใช้ในปลั๊กอินระหว่างการพัฒนา และสิ่งที่ถูก transpile ลงมาเมื่อสร้าง graphql-api.zip
Union types
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data): string | int | null | Error;
}Transpile แล้ว:
interface CustomPostTypeAPIInterface
{
public function createCustomPost(array $data)
}pseudo type mixed
interface CMSServiceInterface
{
public function getOption(string $option, mixed $default = false): mixed;
}Transpile แล้ว:
interface CMSServiceInterface
{
public function getOption(string $option, $default = false);
}magic constant ::class บน objects
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = $directiveResolver::class;
}Transpile แล้ว:
foreach ($directiveResolvers as $directiveResolver) {
$directiveResolverName = $directiveResolver->getDirectiveName();
$this->directiveNameClasses[$directiveResolverName][] = get_class($directiveResolver);
}expressions 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;
}Transpile แล้ว:
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 exceptions เฉพาะตาม type
try {
// ...
} catch (InvalidArgumentException) {
return sprintf(
'<p>%s</p>',
\__('Oops, the documentation for this module is not available', 'graphql-api')
);
}Transpile แล้ว:
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);
}Transpile แล้ว:
public function getSchemaDirectiveDeprecationDescription(TypeResolverInterface $typeResolver): ?string
{
return $this->getSchemaDefinitionResolver($typeResolver) ? $this->getSchemaDefinitionResolver($typeResolver)->getSchemaDirectiveDeprecationDescription($typeResolver) : null;
}Class constructor property promotion
abstract class AbstractEndpointResolver
{
function __construct(protected EndpointHelpers $endpointHelpers)
{
}
}Transpile แล้ว:
abstract class AbstractEndpointResolver
{
/**
* @var \GraphQLAPI\GraphQLAPI\Services\Helpers\EndpointHelpers
*/
protected $endpointHelpers;
function __construct(EndpointHelpers $endpointHelpers)
{
$this->endpointHelpers = $endpointHelpers;
}
}Trailing commas ในรายการ parameters และรายการ use ของ closure
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass(
$typeResolver,
$fieldName,
);
}Transpile แล้ว:
public function resolveFieldTypeResolverClass(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
switch ($fieldName) {
case 'accessControlLists':
return CustomPostTypeResolver::class;
}
return parent::resolveFieldTypeResolverClass($typeResolver, $fieldName);
}