PDO Attribute: การตั้งค่า Attribute ของ PDO
ในบทที่แล้ว เราได้เรียนรู้วิธีการเชื่อมต่อกับฐานข้อมูล MySQL โดยใช้ PDO ใน PHP บทนี้เราจะมาเจาะลึกถึงการปรับแต่ง PDO object ให้เหมาะสมกับการใช้งานของเรามากขึ้น โดยการตั้งค่า Attribute ต่างๆ ของ PDO
Attribute ใน PDO เปรียบเสมือนตัวเลือกหรือค่ากำหนดที่เราสามารถตั้งค่าให้กับ PDO object เพื่อควบคุมพฤติกรรมต่างๆ เช่น การจัดการข้อผิดพลาด, รูปแบบการดึงข้อมูล, และการจำลอง Prepared Statements ซึ่งการปรับแต่ง Attribute เหล่านี้ จะช่วยให้เราเขียนโค้ดได้มีประสิทธิภาพมากขึ้น และจัดการกับปัญหาต่างๆ ได้อย่างเหมาะสม
Attribute สำคัญที่ควรรู้
มี Attribute หลายตัวที่เราสามารถตั้งค่าให้กับ PDO object ได้ แต่ในบทนี้เราจะเน้นไปที่ 3 Attribute หลักๆ ที่มักถูกใช้งานบ่อย และมีความสำคัญต่อการพัฒนาโปรแกรมที่ปลอดภัยและมีประสิทธิภาพ ได้แก่:
PDO::ATTR_ERRMODE: กำหนดวิธีการจัดการข้อผิดพลาดPDO::ATTR_DEFAULT_FETCH_MODE: กำหนดรูปแบบการดึงข้อมูลเริ่มต้นPDO::ATTR_EMULATE_PREPARES: กำหนดว่าจะให้ PDO จำลอง Prepared Statements หรือไม่
PDO::ATTR_ERRMODE: การจัดการข้อผิดพลาด
PDO::ATTR_ERRMODE เป็น Attribute ที่ใช้กำหนดวิธีการจัดการข้อผิดพลาดที่เกิดขึ้นระหว่างการทำงานกับฐานข้อมูล โดยเราสามารถกำหนดค่าได้ 3 รูปแบบ:
PDO::ERRMODE_SILENT: (ค่าเริ่มต้น) PDO จะไม่แสดงข้อผิดพลาดใดๆ แต่จะเก็บข้อมูลข้อผิดพลาดไว้ใน PDO object ซึ่งเราสามารถตรวจสอบได้ภายหลังPDO::ERRMODE_WARNING: PDO จะแสดงข้อผิดพลาดในรูปแบบของ PHP warningPDO::ERRMODE_EXCEPTION: PDO จะ throw exception เมื่อเกิดข้อผิดพลาด ซึ่งเป็นวิธีที่แนะนำ เพราะช่วยให้เราสามารถจัดการข้อผิดพลาดได้อย่างเป็นระบบด้วยtry...catchblock
ตัวอย่างการตั้งค่า PDO::ATTR_ERRMODE เป็น PDO::ERRMODE_EXCEPTION:
<?php
$host = 'localhost';
$dbname = 'mydatabase';
$username = 'root';
$password = 'password';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
// ตั้งค่า ERRMODE เป็น EXCEPTION
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
จากตัวอย่างข้างต้น หากเกิดข้อผิดพลาดในการเชื่อมต่อฐานข้อมูล PDO จะ throw PDOException ซึ่งเราสามารถจับ exception นี้ได้ด้วย try...catch block และแสดงข้อความผิดพลาดที่เหมาะสม
ข้อดีของการใช้ PDO::ERRMODE_EXCEPTION:
- ช่วยให้โค้ดของเรามีความ robust มากขึ้น เพราะเราสามารถจัดการกับข้อผิดพลาดที่อาจเกิดขึ้นได้อย่างเป็นระบบ
- ช่วยให้เรา debug โค้ดได้ง่ายขึ้น เพราะเราสามารถเห็นข้อผิดพลาดได้อย่างชัดเจน
- ช่วยให้เราป้องกันการรั่วไหลของข้อมูลที่สำคัญ เช่น ข้อมูลการเชื่อมต่อฐานข้อมูล
PDO::ATTR_DEFAULT_FETCH_MODE: การกำหนดรูปแบบการดึงข้อมูลเริ่มต้น
PDO::ATTR_DEFAULT_FETCH_MODE เป็น Attribute ที่ใช้กำหนดรูปแบบการดึงข้อมูลเริ่มต้นเมื่อเราใช้ fetch() หรือ fetchAll() โดยเราสามารถกำหนดค่าได้หลายรูปแบบ เช่น:
PDO::FETCH_ASSOC: ดึงข้อมูลในรูปแบบของ associative array โดยใช้ชื่อ column เป็น keyPDO::FETCH_NUM: ดึงข้อมูลในรูปแบบของ numerical array โดยใช้ index เป็น keyPDO::FETCH_BOTH: (ค่าเริ่มต้น) ดึงข้อมูลทั้งในรูปแบบ associative array และ numerical arrayPDO::FETCH_OBJ: ดึงข้อมูลในรูปแบบของ object โดยแต่ละ column จะเป็น property ของ object
ตัวอย่างการตั้งค่า PDO::ATTR_DEFAULT_FETCH_MODE เป็น PDO::FETCH_ASSOC:
<?php
$host = 'localhost';
$dbname = 'mydatabase';
$username = 'root';
$password = 'password';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
// ตั้งค่า DEFAULT_FETCH_MODE เป็น FETCH_ASSOC
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$stmt = $pdo->query("SELECT id, name, email FROM users");
$users = $stmt->fetchAll();
foreach ($users as $user) {
echo "ID: " . $user['id'] . "<br>";
echo "Name: " . $user['name'] . "<br>";
echo "Email: " . $user['email'] . "<br><br>";
}
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
จากตัวอย่างข้างต้น เราได้ตั้งค่า PDO::ATTR_DEFAULT_FETCH_MODE เป็น PDO::FETCH_ASSOC ดังนั้นเมื่อเราใช้ fetchAll() ข้อมูลที่ได้จะเป็น associative array ซึ่งเราสามารถเข้าถึงข้อมูลได้โดยใช้ชื่อ column เป็น key เช่น $user['id'], $user['name'], $user['email']
การตั้งค่า PDO::ATTR_DEFAULT_FETCH_MODE ช่วยให้เราไม่ต้องระบุรูปแบบการดึงข้อมูลในทุกครั้งที่เราเรียกใช้ fetch() หรือ fetchAll() ทำให้โค้ดของเราสั้นลงและอ่านง่ายขึ้น
PDO::ATTR_EMULATE_PREPARES: การจำลอง Prepared Statements
PDO::ATTR_EMULATE_PREPARES เป็น Attribute ที่ใช้กำหนดว่าจะให้ PDO จำลอง Prepared Statements หรือไม่ โดย Prepared Statements เป็นเทคนิคที่สำคัญในการป้องกัน SQL Injection ซึ่งเราจะพูดถึงในบทต่อๆ ไป
โดยปกติแล้ว PDO จะพยายามใช้ Prepared Statements ที่ native ของฐานข้อมูล (ถ้ามี) แต่ในบางกรณี (เช่น ฐานข้อมูลรุ่นเก่า) อาจไม่รองรับ Prepared Statements แบบ native ทำให้ PDO ต้องจำลอง Prepared Statements แทน
ค่าที่เป็นไปได้ของ PDO::ATTR_EMULATE_PREPARES:
true: ให้ PDO จำลอง Prepared Statementsfalse: (ค่าเริ่มต้น) ให้ PDO ใช้ Prepared Statements แบบ native ถ้ามี
ตัวอย่างการตั้งค่า PDO::ATTR_EMULATE_PREPARES เป็น false:
<?php
$host = 'localhost';
$dbname = 'mydatabase';
$username = 'root';
$password = 'password';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
// ตั้งค่า EMULATE_PREPARES เป็น false
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
โดยทั่วไปแล้ว เราไม่จำเป็นต้องเปลี่ยนค่า PDO::ATTR_EMULATE_PREPARES จากค่าเริ่มต้น (false) ยกเว้นในกรณีที่เราต้องการทดสอบพฤติกรรมของ Prepared Statements แบบจำลอง หรือเมื่อเราพบปัญหาในการใช้ Prepared Statements แบบ native
ข้อควรระวัง: การตั้งค่า PDO::ATTR_EMULATE_PREPARES เป็น true อาจทำให้เกิดช่องโหว่ SQL Injection ได้ หากเราไม่ได้ใช้ Prepared Statements อย่างถูกต้อง ดังนั้นควรใช้ด้วยความระมัดระวัง
สรุป
ในบทนี้ เราได้เรียนรู้เกี่ยวกับการตั้งค่า Attribute ต่างๆ ของ PDO เพื่อปรับแต่งพฤติกรรมของ PDO object ให้เหมาะสมกับการใช้งานของเรา โดยเฉพาะ PDO::ATTR_ERRMODE, PDO::ATTR_DEFAULT_FETCH_MODE, และ PDO::ATTR_EMULATE_PREPARES ซึ่งเป็น Attribute ที่สำคัญและมักถูกใช้งานบ่อย
การตั้งค่า Attribute เหล่านี้อย่างถูกต้อง จะช่วยให้เราเขียนโค้ดได้มีประสิทธิภาพมากขึ้น จัดการกับข้อผิดพลาดได้อย่างเป็นระบบ และป้องกันปัญหาด้านความปลอดภัยที่อาจเกิดขึ้นได้
ในบทต่อไป เราจะมาเรียนรู้เกี่ยวกับการใช้งาน Prepared Statements ซึ่งเป็นเทคนิคที่สำคัญในการป้องกัน SQL Injection และเป็นพื้นฐานสำคัญในการพัฒนาโปรแกรมที่ปลอดภัย