ป้ายกำกับ: ประเภท

  • PHP: Scalar Type Hinting ของ Function

    ในยุคก่อนหน้านี้ PHP ขึ้นชื่อว่าเป็นภาษาแบบ Dynamically Typed หรือภาษาที่ไม่มีการผูกมัดประเภทของข้อมูลอย่างเข้มงวด นักพัฒนาสามารถส่งค่าอะไรก็ได้เข้าไปในฟังก์ชัน ซึ่งแม้จะให้ความยืดหยุ่นสูง แต่ก็มักนำมาซึ่งบั๊กซ่อนแอบที่หาตัวจับได้ยากในโปรเจกต์ขนาดใหญ่

    จนกระทั่งการมาถึงของ PHP 7 ระบบได้เปิดตัว Scalar Type Hinting อย่างเป็นทางการ และถูกพัฒนาให้ยอดเยี่ยมยิ่งขึ้นใน PHP 8 ช่วยให้เราสามารถระบุประเภทข้อมูล (Type) ให้กับทั้งโปรแกรมพารามิเตอร์ (Argument) และค่าที่ส่งกลับคืนมา (Return Value) ได้อย่างชัดเจน


    ทำไมต้องระบุ Type Hinting?

    1. ลดบั๊กและข้อผิดพลาด (Bug Reduction): ป้องกันไม่ให้ส่งข้อมูลผิดประเภทเข้าฟังก์ชัน เช่น การนำสตริงไปคำนวณทางคณิตศาสตร์
    2. โค้ดอ่านง่ายขึ้น (Readability): นักพัฒนาคนอื่น (หรือตัวคุณเองในอีก 3 เดือนข้างหน้า) สามารถดูจาก Signature ของฟังก์ชันแล้วรู้ได้ทันทีว่าฟังก์ชันนี้ต้องการอะไร และจะส่งอะไรกลับมา
    3. 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 ได้อย่างมั่นใจ


    อ่านเพิ่มเติม