PHP 8: kode "Sebelum" dan "Sesudah" (perbandingan dengan PHP 7.4)





Hanya ada beberapa bulan tersisa sampai PHP 8 keluar, dan ada banyak hal bagus dalam rilis ini. Di bawah potongan, kami akan memberi tahu Anda bagaimana inovasi ini sudah mulai mengubah pendekatan penulis untuk menulis kode.



Pelanggan acara dengan atribut



Saya akan mencoba untuk tidak menggunakan atribut secara berlebihan, tetapi dalam kasus menyiapkan pendengar acara, misalnya, atribut sangat berguna.



Baru-baru ini saya telah mengerjakan sistem di mana ada banyak pengaturan seperti itu. Mari kita ambil contoh:



class CartsProjector implements Projector
{
    use ProjectsEvents;

    protected array $handlesEvents = [
        CartStartedEvent::class => 'onCartStarted',
        CartItemAddedEvent::class => 'onCartItemAdded',
        CartItemRemovedEvent::class => 'onCartItemRemoved',
        CartExpiredEvent::class => 'onCartExpired',
        CartCheckedOutEvent::class => 'onCartCheckedOut',
        CouponAddedToCartItemEvent::class => 'onCouponAddedToCartItem',
    ];

    public function onCartStarted(CartStartedEvent $event): void
    { /* … */ }

    public function onCartItemAdded(CartItemAddedEvent $event): void
    { /* … */ }

    public function onCartItemRemoved(CartItemRemovedEvent $event): void
    { /* … */ }

    public function onCartCheckedOut(CartCheckedOutEvent $event): void
    { /* … */ }

    public function onCartExpired(CartExpiredEvent $event): void
    { /* … */ }

    public function onCouponAddedToCartItem(CouponAddedToCartItemEvent $event): void
    { /* … */ }
}






Atribut PHP 7 di PHP 8 memiliki dua keunggulan:



  • Kode untuk menyiapkan pendengar dan penangan acara dikumpulkan di satu tempat, dan saya tidak perlu menggulir ke awal untuk melihat apakah pendengar disiapkan dengan benar.
  • Saya tidak perlu lagi khawatir tentang menulis dan memanipulasi nama metode sebagai string (ketika IDE tidak dapat melengkapinya secara otomatis, tidak ada analisis statis kesalahan ketik dan penggantian nama metode tidak berfungsi).


class CartsProjector implements Projector
{
    use ProjectsEvents;

    @@SubscribesTo(CartStartedEvent::class)
    public function onCartStarted(CartStartedEvent $event): void
    { /* … */ }

    @@SubscribesTo(CartItemAddedEvent::class)
    public function onCartItemAdded(CartItemAddedEvent $event): void
    { /* … */ }

    @@SubscribesTo(CartItemRemovedEvent::class)
    public function onCartItemRemoved(CartItemRemovedEvent $event): void
    { /* … */ }

    @@SubscribesTo(CartCheckedOutEvent::class)
    public function onCartCheckedOut(CartCheckedOutEvent $event): void
    { /* … */ }

    @@SubscribesTo(CartExpiredEvent::class)
    public function onCartExpired(CartExpiredEvent $event): void
    { /* … */ }

    @@SubscribesTo(CouponAddedToCartItemEvent::class)
    public function onCouponAddedToCartItem(CouponAddedToCartItemEvent $event): void
    { /* … */ }
}


PHP 8



Statis, bukan blok dokumen



Ini bukan perubahan besar, tapi saya melihatnya setiap hari. Saya sering menemukan bahwa saya masih memerlukan blok dokumen ketika saya perlu menentukan bahwa suatu fungsi memiliki tipe pengembalian statis.



Jika di PHP 7.4 saya perlu menulis:



/**
 * @return static
 */
public static function new()
{
    return new static();
}


PHP 7.4



Maka sudah cukup sekarang:



public static function new(): static
{
    return new static();
}


PHP 8



DTO, meneruskan properti dan argumen bernama



Saya telah menulis sedikit tentang penggunaan sistem tipe PHP dan pola DTO ( objek transfer data ). Secara alami, saya banyak menggunakan DTO dalam kode saya sendiri, jadi Anda dapat membayangkan betapa bahagianya saya sekarang dapat menulis ulang ini:



class CustomerData extends DataTransferObject
{
    public string $name;

    public string $email;

    public int $age;
    
    public static function fromRequest(
        CustomerRequest $request
    ): self {
        return new self([
            'name' => $request->get('name'),
            'email' => $request->get('email'),
            'age' => $request->get('age'),
        ]);
    }
}

$data = CustomerData::fromRequest($customerRequest);


PHP 7.4



Di sini, itu lebih baik:



class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(...$customerRequest->validated());


PHP 8



Perhatikan penggunaan properti konstruktor yang lewat sebagai parameter bernama. Ya, mereka dapat diteruskan menggunakan array bernama dan operator Spread.



Enumeration and match



Apakah Anda menggunakan enum dengan beberapa metode yang mengembalikan hasil tergantung pada nilai spesifik dari pencacahan?



/**
 * @method static self PENDING()
 * @method static self PAID()
 */
class InvoiceState extends Enum
{
    private const PENDING = 'pending';
    private const PAID = 'paid';

    public function getColour(): string
    {
        return [
            self::PENDING => 'orange',
            self::PAID => 'green',
        ][$this->value] ?? 'gray';   
    }
}


PHP 7.4



Saya akan mengatakan bahwa untuk kondisi yang lebih kompleks Anda lebih baik menggunakan pola Negara, tetapi ada kasus di mana pencacahan sudah cukup. Sintaks array aneh ini sudah menjadi singkatan untuk ekspresi bersyarat yang lebih rumit:



/**
 * @method static self PENDING()
 * @method static self PAID()
 */
class InvoiceState extends Enum
{
    private const PENDING = 'pending';
    private const PAID = 'paid';

    public function getColour(): string
    {
        if ($this->value === self::PENDING) {
            return 'orange';
        }
    
        if ($this->value === self::PAID) {
            return 'green'
        }

        return 'gray';
    }
}


PHP 7.4 - Alternatif



Tapi di PHP 8 kita bisa menggunakan pertandingan sebagai gantinya.



/**
 * @method static self PENDING()
 * @method static self PAID()
 */
class InvoiceState extends Enum
{
    private const PENDING = 'pending';
    private const PAID = 'paid';

    public function getColour(): string
    {
        return match ($this->value) {
            self::PENDING => 'orange',
            self::PAID => 'green',
            default => 'gray',
        };
}


PHP 8



Bergabung, bukan blok dokumen



Ini bekerja dengan cara yang mirip dengan apa yang dijelaskan sebelumnya untuk tipe pengembalian statis.



/**
 * @param string|int $input
 *
 * @return string 
 */
public function sanitize($input): string;


PHP 7,4



public function sanitize(string|int $input): string;


PHP 8



Melempar Pengecualian



Sebelumnya, Anda tidak dapat menggunakan lemparan dalam ekspresi, yang berarti Anda harus menulis, misalnya, pemeriksaan berikut:



public function (array $input): void
{
    if (! isset($input['bar'])) {
        throw BarIsMissing::new();
    }
    
    $bar = $input['bar'];

    // …
}


PHP 7.4



Dalam PHP 8, throw menjadi sebuah ekspresi, yang artinya Anda dapat menggunakannya seperti ini:



public function (array $input): void
{
    $bar = $input['bar'] ?? throw BarIsMissing::new();

    // …
}


PHP 8



Operator Nullsafe



Jika Anda terbiasa dengan operator penggabungan null, Anda akan menyadari kekurangannya: operator ini tidak berfungsi dengan panggilan metode. Oleh karena itu, saya sering membutuhkan pemeriksaan perantara atau fungsi kerangka kerja yang sesuai untuk tujuan ini:



$startDate = $booking->getStartDate();
$dateAsString = $startDate ? $startDate->asDateTimeString() : null;


PHP 7.4



Dengan diperkenalkannya operator nullsafe, saya dapat mengatasi masalah ini dengan lebih mudah.



$dateAsString = $booking->getStartDate()?->asDateTimeString();


PHP 8



Inovasi apa di PHP 8 yang menurut Anda penting?






Periklanan



Server untuk mengembangkan dan menampung proyek Anda. Setiap server terhubung ke saluran 500 Megabit yang dilindungi dari serangan DDoS, dimungkinkan untuk menggunakan jaringan lokal berkecepatan tinggi. Kami menawarkan berbagai macam rencana tarif, perubahan tarif dalam satu klik. Panel kontrol server yang sangat nyaman dan kemampuan untuk menggunakan API. Cepat periksa!






All Articles