ป้ายกำกับ: ยอดนิยม

PHP: การป้องกัน SQL Injection ด้วย PDO Prepared StatementsPHP: การป้องกัน SQL Injection ด้วย PDO Prepared Statements

ในการพัฒนาเว็บแอปพลิเคชันด้วย PHP สิ่งสำคัญอันดับต้นๆ ที่นักพัฒนาต้องคำนึงถึงคือความปลอดภัยของข้อมูลครับ โดยเฉพาะช่องโหว่ยอดนิยมอย่าง SQL Injection ซึ่งเป็นการที่ผู้ไม่หวังดีส่งคำสั่ง SQL แปลกปลอมผ่านทาง Form หรือ URL เพื่อเข้ามาขโมยหรือทำลายฐานข้อมูลของเรา


ทำความรู้จัก PDO และ Prepared Statements

ทางออกที่เป็นมาตรฐานสากลในปัจจุบันคือการใช้ PDO (PHP Data Objects) ร่วมกับ Prepared Statements ครับ หลักการทำงานคือการแยก “โครงสร้างคำสั่ง SQL” ออกจาก “ข้อมูล” อย่างเด็ดขาด ทำให้ฐานข้อมูลมองว่าข้อมูลที่ส่งเข้ามาเป็นเพียงตัวอักษรธรรมดา ไม่ใช่ส่วนหนึ่งของคำสั่งที่จะเอาไปรันได้


ตัวอย่างการใช้งาน PDO Prepared Statements

แทนที่เราจะเอาตัวแปรไปใส่ใน Query ตรง ๆ เราจะใช้สิ่งที่เรียกว่า Placeholder (เครื่องหมาย : ตามด้วยชื่อตัวแปร) แทน ดังนี้ครับ

// 1. เชื่อมต่อฐานข้อมูลด้วย PDO
$pdo = new PDO("mysql:host=localhost;dbname=my_database", "db_user", "db_pass");

// 2. เตรียมคำสั่ง SQL (ใช้ Named Placeholder)
$sql = "SELECT id, username FROM users WHERE email = :email AND status = :status";
$stmt = $pdo->prepare($sql);

// 3. ผูกข้อมูลและสั่งรันคำสั่ง (Binding and Executing)
$stmt->execute([
    ':email'  => $_POST['email'],
    ':status' => 'active'
]);

// 4. ดึงข้อมูลออกมาใช้งาน
$user = $stmt->fetch();


ทำไมวิธีนี้ถึงปลอดภัย?

เมื่อเราใช้ฟังก์ชัน prepare() ฐานข้อมูลจะทำการประมวลผลโครงสร้างของ Query รอไว้ก่อนแล้ว และเมื่อเราส่งค่าตัวแปรตามไปทีหลังผ่าน execute() ฐานข้อมูลจะนำค่านั้นไปวางในช่องว่างที่เตรียมไว้โดยไม่มีการตีความว่าเป็นคำสั่งใหม่ ดังนั้นต่อให้ User ใส่ค่าอย่าง ' OR '1'='1 เข้ามา ระบบก็จะมองว่าเป็นเพียง “ข้อความยาว ๆ ชุดหนึ่ง” เท่านั้น ไม่สามารถเปลี่ยนโครงสร้างคำสั่งเดิมได้เลยครับ


ข้อดีของการใช้ PDO

  • รองรับฐานข้อมูลหลากหลาย: PDO สามารถสลับไปใช้ Database อื่นได้ง่าย เช่น MySQL, PostgreSQL หรือ SQLite โดยแทบไม่ต้องแก้โค้ดหลัก
  • จัดการ Error ได้ดี: มีระบบ Exception ที่ช่วยให้เราดักจับข้อผิดพลาดและจัดการได้อย่างเป็นระบบ
  • โค้ดอ่านง่าย: การแยก Logic ออกจาก Data ทำให้โค้ดสะอาดและดูแลรักษาได้ง่ายในระยะยาว

สรุป

การเปลี่ยนจากการเชื่อมต่อแบบเดิมมาใช้ PDO Prepared Statements ไม่ใช่เรื่องของความชอบ แต่เป็นเรื่องของ “ความรับผิดชอบ” ต่อความปลอดภัยของข้อมูลผู้ใช้งานครับ หากคุณใช้ PHP 8+ การใช้วิธีนี้ถือเป็นมาตรฐานขั้นพื้นฐานที่ขาดไม่ได้เลยครับ


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