PHP 8.3 มีอะไรใหม่

ไล่ดูฟีเจอร์ของ PHP 8.3 ที่ได้ใช้ในโค้ดทั่วไป ตั้งแต่ typed class constants, #[\Override], json_validate() ไปจนถึงเรียก constant ด้วยชื่อในตัวแปร พร้อมตัวอย่างที่รันได้จริง

เผยแพร่
อัปเดต
— แก้ตัวอย่าง #[\Override] และเพิ่มสถานะซัพพอร์ตของ PHP 8.3
เวลาอ่าน
3 นาที
สรุปจาก
Brent Roose · stitcher.io
แท็ก
#PHP
ในโพสต์นี้ 7 หัวข้อ
  1. ใส่ type ให้ class constant ได้แล้ว
  2. #[\Override] เช็กให้ว่าเมธอดยัง override parent class อยู่จริง
  3. Index ติดลบใน array นับต่อจากตัวล่าสุดแล้ว
  4. คลาส anonymous ประกาศเป็น readonly ได้
  5. เช็กว่า string เป็น JSON ที่ถูกต้องด้วย json_validate()
  6. เรียก class constant ด้วยชื่อที่อยู่ในตัวแปร
  7. ของอื่นที่มากับ PHP 8.3

ใส่ type ให้ class constant ได้แล้ว

ก่อน PHP 8.3 เราประกาศ const ในคลาสได้แค่ชื่อกับค่า ระบุ type ไม่ได้ ตั้งแต่ PHP 8.3 ใส่ type ไว้หน้าชื่อได้เหมือน property เรียกว่า typed class constants

class Post
{
    // ก่อน PHP 8.3 ระบุ type ไม่ได้
    const STATUS_DRAFT = 'draft';

    // PHP 8.3 ใส่ type ได้แล้ว
    const string STATUS_PUBLIC = 'public';
}

ถ้าใส่ค่าที่ไม่ตรงกับ type เช่น const string STATUS_PUBLIC = 1; PHP จะหยุดทันทีด้วย error นี้

Fatal error: Cannot use int as value for class constant Post::STATUS_PUBLIC of type string

RFC

#[\Override] เช็กให้ว่าเมธอดยัง override parent class อยู่จริง

ใส่ attribute #[\Override] บนเมธอดเพื่อบอกว่าเราตั้งใจ override เมธอดของ parent class (หรือของ interface) ถ้าวันหนึ่ง parent class เปลี่ยนชื่อเมธอด เมธอดใน child class ก็ไม่ได้ override อะไรแล้ว PHP จะฟ้อง error ให้เรารู้ตัว แทนที่โค้ดจะเงียบไปเฉย ๆ

abstract class BaseClass
{
    public function methodWithDefaultImplementation(): int
    {
        return 1;
    }
}

class Child extends BaseClass
{
    #[\Override]
    public function methodWithDefaultImplementation(): int
    {
        return 2; // override เมธอดของ parent class
    }
}

ทีนี้ถ้า parent class เปลี่ยนชื่อเมธอดเป็นชื่ออื่น

abstract class BaseClass
{
    public function methodWithNewImplementation(): int
    {
        return 1;
    }
}

Child::methodWithDefaultImplementation() ก็ไม่ได้ override เมธอดไหนแล้ว PHP เห็น #[\Override] จึงหยุดด้วย error นี้

Fatal error: Child::methodWithDefaultImplementation() has #[\Override] attribute, but no matching parent method exists

RFC

Index ติดลบใน array นับต่อจากตัวล่าสุดแล้ว

สมมติเรามี array เปล่า แล้วใส่ค่าที่ index ติดลบ เช่น -5 จากนั้นเพิ่มค่าถัดไปด้วย $array[] = … ก่อน PHP 8.3 ค่าถัดไปจะกระโดดไปเริ่มที่ index 0 ส่วน PHP 8.3 นับต่อจาก -5 เป็น -4

$array = [];

$array[-5] = 'a';
$array[] = 'b';

var_export($array);

ผลลัพธ์ที่ได้ในแต่ละเวอร์ชัน

array (
  -5 => 'a',
  0 => 'b',
)

PHP 8.0 แก้เรื่องนี้ไปแล้วรอบหนึ่งสำหรับ array ที่ประกาศพร้อม key ติดลบ เช่น [-5 => 'a'] แต่ยังตกกรณีใส่ค่าลงใน array เปล่า ซึ่ง PHP 8.3 มาเก็บให้ครบ (UPGRADING ของ PHP 8.3)

คลาส anonymous ประกาศเป็น readonly ได้

PHP 8.2 ให้เราประกาศ readonly class ได้แล้ว แต่ยังใช้กับคลาส anonymous ไม่ได้ PHP 8.3 เติมส่วนนี้ให้

$class = new readonly class {
    public function __construct(
        public string $foo = 'bar',
    ) {}
};

$class->foo = 'baz'; // Error: Cannot modify readonly property class@anonymous::$foo

RFC

เช็กว่า string เป็น JSON ที่ถูกต้องด้วย json_validate()

ที่ผ่านมา ถ้าอยากรู้ว่า string เป็น JSON ที่ถูกต้องไหม เราต้อง json_decode() ทั้งก้อนแล้วดู json_last_error() PHP 8.3 เพิ่ม json_validate() ที่เช็กอย่างเดียว ไม่ต้องสร้าง array หรือ object ออกมา จึงกินหน่วยความจำน้อยกว่า

json_validate(string $json, int $depth = 512, int $flags = 0): bool
// ก่อน PHP 8.3
json_decode($json);
$isValid = json_last_error() === JSON_ERROR_NONE;

// PHP 8.3
$isValid = json_validate($json);

json_validate('{"name": "PHP"}'); // true
json_validate('{name: PHP}');     // false

RFC

เรียก class constant ด้วยชื่อที่อยู่ในตัวแปร

ถ้าชื่อ constant อยู่ในตัวแปร PHP 8.3 ให้เราเขียน Foo::{$name} ได้ตรง ๆ ไม่ต้องต่อ string แล้วส่งให้ constant()

class Foo
{
    const BAR = 'bar';
}

$name = 'BAR';

// ก่อน PHP 8.3
constant(Foo::class . '::' . $name); // 'bar'

// PHP 8.3
Foo::{$name}; // 'bar'

RFC

ของอื่นที่มากับ PHP 8.3

PHP 8.3 ยังเพิ่มเมธอดใหม่ใน Randomizer, ฟังก์ชัน mb_str_pad(), ตรวจจับ stack overflow และ deprecate ของเล็ก ๆ อีกหลายข้อ อ่านรายการเต็มได้ที่หน้า release ของ php.net และ php.watch

อ่านต่อ

ถูกอ้างถึงใน

ล่าสุด

ดูทั้งหมด →