นำ PHP ยุคปัจจุบันมาใช้: strict types, arrow function, ตัวดำเนินการ nullsafe, enum และนิพจน์ match
เปิดบทเรียนนี้ใน KodokonPHP สมัยใหม่โอบรับการกำหนดชนิด declare(strict_types=1) ที่วางไว้เป็นคำสั่งแรกของไฟล์ จะปิดการแปลงชนิดโดยปริยาย การส่งสายอักขระ '10' ให้พารามิเตอร์ชนิด float จะโยน TypeError แทนที่จะถูกแปลงเงียบ ๆ จงกำหนดชนิดให้กับ พารามิเตอร์และค่าที่คืนกลับ ข้อผิดพลาดของคุณจะปรากฏขึ้นแต่เนิ่น ๆ ในที่ที่ถูกต้อง แทนที่จะโผล่มาอีกสามไฟล์ถัดไป
<?php
declare(strict_types=1);
function applyDiscount(
float $price,
float $rate = 0.1
): float {
return round($price * (1 - $rate), 2);
}
echo applyDiscount(49.99);
echo PHP_EOL;
echo applyDiscount(100.0, 0.25);Arrow function fn ย่นย่อฟังก์ชันนิรนามที่มีเพียงนิพจน์เดียว ข้อได้เปรียบสำคัญเหนือโคลเชอร์แบบดั้งเดิม: มันจับตัวแปรจากขอบเขตแม่โดยอัตโนมัติ โดยไม่ต้องใช้อนุประโยค use มันโดดเด่นเมื่อใช้กับ array_map() และ array_filter()
<?php
declare(strict_types=1);
$prices = [12.5, 49.9, 8.0, 120.0];
$rate = 0.2;
$discounted = array_map(
fn (float $p): float => round($p * (1 - $rate), 2),
$prices
);
$affordable = array_filter(
$discounted,
fn (float $p): bool => $p < 50
);
print_r($affordable);ตัวดำเนินการ nullsafe ?-> จะตัดการเรียกให้ลัดวงจรทันทีที่ข้อต่อในสายโซ่เป็น null แทนที่จะทำให้เกิดข้อผิดพลาดร้ายแรง เมื่อผสมกับ ?? มันจะแทนที่พีระมิดของคำสั่ง if ด้วยบรรทัดเดียวที่อ่านง่าย
<?php
declare(strict_types=1);
class Address
{
public function __construct(
public readonly string $city
) {
}
}
class User
{
public function __construct(
public readonly ?Address $address = null
) {
}
}
$alice = new User(new Address('Lyon'));
$bob = new User();
echo $alice->address?->city ?? 'Unknown city';
echo PHP_EOL;
echo $bob->address?->city ?? 'Unknown city';Enum มอบชนิดที่แท้จริงให้กับชุดค่าที่ปิดตายตัว (สถานะ บทบาท) จนเป็นไปไม่ได้ที่จะสร้างสถานะที่ไม่มีอยู่จริง และ match คือการพัฒนาที่ชัดเจนเหนือ switch เปรียบเทียบอย่างเข้มงวด คืนผลลัพธ์ออกมาเป็นค่า และมี UnhandledMatchError หากไม่มีกรณีใดตรงกัน เป็นเกราะป้องกันความหลงลืม
<?php
declare(strict_types=1);
enum OrderStatus: string
{
case Pending = 'pending';
case Shipped = 'shipped';
case Delivered = 'delivered';
public function label(): string
{
return match ($this) {
self::Pending => 'Pending',
self::Shipped => 'Shipped',
self::Delivered => 'Delivered',
};
}
}
$status = OrderStatus::from('shipped');
echo $status->label();