ในยุคก่อนหน้านี้ PHP ขึ้นชื่อว่าเป็นภาษาแบบ Dynamically Typed หรือภาษาที่ไม่มีการผูกมัดประเภทของข้อมูลอย่างเข้มงวด นักพัฒนาสามารถส่งค่าอะไรก็ได้เข้าไปในฟังก์ชัน ซึ่งแม้จะให้ความยืดหยุ่นสูง แต่ก็มักนำมาซึ่งบั๊กซ่อนแอบที่หาตัวจับได้ยากในโปรเจกต์ขนาดใหญ่
จนกระทั่งการมาถึงของ PHP 7 ระบบได้เปิดตัว Scalar Type Hinting อย่างเป็นทางการ และถูกพัฒนาให้ยอดเยี่ยมยิ่งขึ้นใน PHP 8 ช่วยให้เราสามารถระบุประเภทข้อมูล (Type) ให้กับทั้งโปรแกรมพารามิเตอร์ (Argument) และค่าที่ส่งกลับคืนมา (Return Value) ได้อย่างชัดเจน
ทำไมต้องระบุ Type Hinting?
- ลดบั๊กและข้อผิดพลาด (Bug Reduction): ป้องกันไม่ให้ส่งข้อมูลผิดประเภทเข้าฟังก์ชัน เช่น การนำสตริงไปคำนวณทางคณิตศาสตร์
- โค้ดอ่านง่ายขึ้น (Readability): นักพัฒนาคนอื่น (หรือตัวคุณเองในอีก 3 เดือนข้างหน้า) สามารถดูจาก Signature ของฟังก์ชันแล้วรู้ได้ทันทีว่าฟังก์ชันนี้ต้องการอะไร และจะส่งอะไรกลับมา
- IDE ทำงานได้ฉลาดขึ้น (Better Tooling): IDE อย่าง VS Code หรือ PHPStorm จะสามารถทำ Auto-complete และแจ้งเตือน Error ได้ตั้งแต่ตอนที่คุณกำลังพิมพ์โค้ด
Argument Type Hinting (การระบุ Type ให้พารามิเตอร์)
เราสามารถระบุ Type ไว้ข้างหน้าชื่อตัวแปรในฟังก์ชันได้ทันที โดย Scalar Types พื้นฐานที่รองรับมีดังนี้
- bool (จริง/เท็จ)
- float (ทศนิยม)
- int (จำนวนเต็ม)
- string (ข้อความ)
ตัวอย่างโค้ด
<?php
function calculateTotal(int $price, int $quantity): int {
return $price * $quantity;
}
// การใช้งานปกติ
echo calculateTotal(100, 3); // ผลลัพธ์: 300
Return Type Hinting (การระบุ Type ให้ค่าที่ส่งกลับ)
เราสามารถกำหนดได้ว่าฟังก์ชันนี้ “ต้อง” Return ค่ากลับมาเป็นข้อมูลประเภทไหน โดยใช้เครื่องหมายโคลอน : ตามด้วยประเภทข้อมูล ไว้หลังวงเล็บของฟังก์ชัน
<?php
function isAdult(int $age): bool {
return $age >= 18;
}
// ถ้ารันฟังก์ชันนี้ จะได้ค่าเป็น true หรือ false เสมอ
var_dump(isAdult(20)); // bool(true)
นอกจาก Scalar Types ทั่วไปแล้ว ยังมี Return Type พิเศษที่น่าสนใจ เช่น
: void— ใช้เมื่อฟังก์ชันนั้นไม่มีการส่งค่ากลับ (ไม่มีreturnหรือมีแค่return;เปล่า ๆ): never— (เพิ่มเข้ามาใน PHP 8.1) สำหรับฟังก์ชันที่ไม่มีวันทำงานเสร็จสมบูรณ์ เช่น ฟังก์ชันที่ทำหน้าที่exit()หรือthrow exceptionเสมอ
โหมดการทำงาน: Coercive vs Strict Mode
นี่คือจุดที่สำคัญที่สุดของ PHP การทำงานของ Type Hinting จะขึ้นอยู่กับว่าคุณเปิด Strict Mode หรือไม่
โหมดปกติ (Coercive Mode – ค่าเริ่มต้น)
PHP จะพยายามแปลงประเภทข้อมูลให้โดยอัตโนมัติ (Type Coercion) หากข้อมูลนั้นพอจะแปลงได้ เช่น ถ้าฟังก์ชันรับ int แต่คุณส่งสตริง "5" เข้าไป PHP จะแปลงเป็นเลข 5 ให้ทันทีโดยไม่แจ้ง Error
<?php
function printNumber(int $num) {
echo $num;
}
printNumber("10"); // ผลลัพธ์: 10 (PHP แปลงจาก string เป็น int ให้ใจดีสุดๆ)
โหมดเข้มงวด (Strict Mode – แนะนำ)
หากคุณต้องการความปลอดภัยสูงสุด คุณต้องเปิดใช้งาน Strict Mode โดยการใส่ตรรกะไว้ที่ บรรทัดแรกสุด ของไฟล์โค้ด (ก่อนโค้ดอื่น ๆ ทั้งหมด) ดังนี้
<?php
declare(strict_types=1); // เปิดใช้งาน Strict Mode
function printNumber(int $num) {
echo $num;
}
printNumber("10");
// ผลลัพธ์: Fatal error: Uncaught TypeError: printNumber(): Argument #1 ($num) must be of type int, string given
ข้อควรระวัง: declare(strict_types=1); จะมีผลเฉพาะภายในไฟล์ที่ระบุไว้เท่านั้น ไม่ส่งผลข้ามไปยังไฟล์อื่นที่ทำ include หรือ require เข้ามา
การต่อยอดใน PHP 8: Union Types และ Mixed Type
ในชีวิตจริง ข้อมูลบางอย่างอาจเป็นไปได้มากกว่าหนึ่งประเภท PHP 8 จึงได้เพิ่มฟีเจอร์เพื่อตอบโจทย์นี้
Union Types (|)
ระบุว่าตัวแปรสามารถเป็น Type ใด Type หนึ่งในกลุ่มที่กำหนดได้ เช่น เป็นได้ทั้ง float หรือ int
<?php
declare(strict_types=1);
// รับได้ทั้ง int และ float และรีเทิร์นได้ทั้ง int และ float
function square(int|float $number): int|float {
return $number * $number;
}
Mixed Type (mixed)
หากตัวแปรนั้นสามารถเป็นอะไรก็ได้จริงๆ (คล้ายกับไม่ใส่ Type ในสมัยก่อน) แต่การใส่ mixed จะช่วยบอกให้เพื่อนร่วมทีมรู้ว่า “เราตั้งใจให้มันเป็นอะไรก็ได้นะ ไม่ใช่ว่าลืมใส่”
<?php
function debugLog(mixed $data): void {
print_r($data);
}
สรุป
การใช้งาน Scalar Type Hinting ควบคู่กับการเปิด declare(strict_types=1); ถือเป็น Best Practice ของการเขียน PHP ในปัจจุบัน มันเปลี่ยนโฉมหน้าของภาษา PHP จากภาษาที่เคยถูกมองว่า “เขียนง่ายแต่พังง่าย” ให้กลายเป็นภาษาที่มีโครงสร้างแข็งแรง ปลอดภัย และเหมาะกับการพัฒนาระบบระดับ Enterprise ได้อย่างมั่นใจ
อ่านเพิ่มเติม