Database Connection: MySQLi
ในบทเรียนก่อนหน้านี้ เราได้เรียนรู้เกี่ยวกับ Abstract Classes และ Interfaces ซึ่งเป็นพื้นฐานสำคัญในการออกแบบเชิงวัตถุที่ยืดหยุ่นและสามารถนำไปประยุกต์ใช้ในการพัฒนาโปรแกรมที่มีขนาดใหญ่และซับซ้อนได้ ในบทนี้ เราจะก้าวเข้าสู่โลกของการจัดการข้อมูล โดยเรียนรู้วิธีการเชื่อมต่อกับฐานข้อมูล MySQL ซึ่งเป็นฐานข้อมูลเชิงสัมพันธ์ (Relational Database) ที่ได้รับความนิยมอย่างแพร่หลาย โดยเราจะใช้ MySQLi extension ซึ่งเป็นส่วนขยายของ PHP ที่ออกแบบมาเพื่อทำงานกับ MySQL โดยเฉพาะ
MySQLi Extension: ทางเลือกที่ทรงพลัง
MySQLi (MySQL Improved) เป็นส่วนขยายที่พัฒนาขึ้นมาเพื่อแก้ไขและปรับปรุงประสิทธิภาพของ MySQL extension เดิม (ซึ่งปัจจุบันไม่แนะนำให้ใช้แล้ว) MySQLi มีคุณสมบัติที่สำคัญหลายประการ ได้แก่:
- รองรับ Prepared Statements: ช่วยป้องกัน SQL Injection ซึ่งเป็นช่องโหว่ด้านความปลอดภัยที่ร้ายแรง
- รองรับ Object-Oriented และ Procedural Styles: ช่วยให้เราเลือกรูปแบบการเขียนโค้ดที่เหมาะสมกับความถนัดและลักษณะของโปรเจกต์
- ประสิทธิภาพที่ดีขึ้น: เมื่อเทียบกับ MySQL extension เดิม
ก่อนที่เราจะเริ่มเขียนโค้ดเพื่อเชื่อมต่อกับฐานข้อมูล เราจำเป็นต้องตรวจสอบให้แน่ใจว่า MySQLi extension ได้ถูกติดตั้งและเปิดใช้งานบนเซิร์ฟเวอร์ของเราแล้ว โดยทั่วไปแล้ว MySQLi จะถูกติดตั้งมาพร้อมกับ PHP แต่หากยังไม่ได้ติดตั้ง เราสามารถติดตั้งได้ผ่าน package manager ของระบบปฏิบัติการ (เช่น apt-get บน Ubuntu หรือ yum บน CentOS) หรือผ่าน PHP extension manager (เช่น pecl)
การสร้าง Connection Object: ขั้นตอนแรกสู่การสื่อสารกับฐานข้อมูล
เมื่อเรามั่นใจว่า MySQLi extension พร้อมใช้งานแล้ว ขั้นตอนต่อไปคือการสร้าง connection object ซึ่งเป็นตัวแทนของการเชื่อมต่อระหว่าง PHP script ของเรากับฐานข้อมูล MySQL เราสามารถสร้าง connection object ได้โดยใช้ constructor ของ mysqli class:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$database = "database_name";
// สร้าง connection object
$conn = new mysqli($servername, $username, $password, $database);
// ตรวจสอบ connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
คำอธิบายโค้ด:
$servername,$username,$password, และ$database: เป็นตัวแปรที่เก็บข้อมูลสำหรับการเชื่อมต่อกับฐานข้อมูล ได้แก่ ชื่อเซิร์ฟเวอร์, ชื่อผู้ใช้, รหัสผ่าน, และชื่อฐานข้อมูล ตามลำดับ เราควรเปลี่ยนค่าเหล่านี้ให้ตรงกับข้อมูลของฐานข้อมูลที่เราต้องการเชื่อมต่อ$conn = new mysqli($servername, $username, $password, $database);: เป็นการสร้าง connection object โดยใช้ constructor ของmysqliclass และส่งข้อมูลสำหรับการเชื่อมต่อเป็น argumentsif ($conn->connect_error) { ... }: เป็นการตรวจสอบว่าการเชื่อมต่อสำเร็จหรือไม่ หากเกิดข้อผิดพลาด (connect_error) จะแสดงข้อความผิดพลาดและหยุดการทำงานของ script ด้วยdie()echo "Connected successfully";: หากการเชื่อมต่อสำเร็จ จะแสดงข้อความ "Connected successfully"
แนวปฏิบัติที่ดี: ควรเก็บข้อมูลสำหรับการเชื่อมต่อ (เช่น ชื่อผู้ใช้, รหัสผ่าน) ไว้ในไฟล์ configuration ที่แยกต่างหาก และไม่ควร hardcode ไว้ใน script โดยตรง เพื่อความปลอดภัยและความสะดวกในการจัดการ
การตรวจสอบ Connection Error: การจัดการข้อผิดพลาดอย่างมีประสิทธิภาพ
การตรวจสอบ connection error เป็นสิ่งสำคัญอย่างยิ่งในการพัฒนาโปรแกรมที่ทำงานกับฐานข้อมูล เนื่องจากข้อผิดพลาดในการเชื่อมต่ออาจเกิดขึ้นได้จากหลายสาเหตุ เช่น ข้อมูลสำหรับการเชื่อมต่อไม่ถูกต้อง, เซิร์ฟเวอร์ฐานข้อมูลไม่พร้อมใช้งาน, หรือสิทธิ์การเข้าถึงไม่ถูกต้อง หากเราไม่ตรวจสอบข้อผิดพลาดเหล่านี้ โปรแกรมของเราอาจทำงานผิดพลาดหรือหยุดทำงานโดยไม่คาดคิด
ในตัวอย่างโค้ดข้างต้น เราได้ใช้ $conn->connect_error เพื่อตรวจสอบข้อผิดพลาดในการเชื่อมต่อ ซึ่งเป็นวิธีที่ง่ายและรวดเร็ว แต่ในโปรเจกต์ที่มีขนาดใหญ่และซับซ้อน เราอาจต้องการวิธีการจัดการข้อผิดพลาดที่ละเอียดและยืดหยุ่นกว่านี้
เราสามารถใช้ try...catch block เพื่อจัดการข้อผิดพลาดในการเชื่อมต่อได้ดังนี้:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$database = "database_name";
try {
// สร้าง connection object
$conn = new mysqli($servername, $username, $password, $database);
// ตรวจสอบ connection
if ($conn->connect_error) {
throw new Exception("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
คำอธิบายโค้ด:
try { ... }: เป็น block ที่เราจะใส่โค้ดที่อาจทำให้เกิดข้อผิดพลาดthrow new Exception("Connection failed: " . $conn->connect_error);: หากเกิดข้อผิดพลาดในการเชื่อมต่อ เราจะสร้างExceptionobject และ throw มันออกมาcatch (Exception $e) { ... }: เป็น block ที่จะรับExceptionobject ที่ถูก throw ออกมา และจัดการกับข้อผิดพลาดนั้น ในที่นี้เราจะแสดงข้อความผิดพลาด
เหตุผลเชิงออกแบบ: การใช้ try...catch block ช่วยให้เราสามารถแยกส่วนของการจัดการข้อผิดพลาดออกจากส่วนของการทำงานหลัก ทำให้โค้ดอ่านง่ายและบำรุงรักษาได้ง่ายขึ้น นอกจากนี้ เรายังสามารถใช้ finally block เพื่อใส่โค้ดที่จะถูก execute เสมอ ไม่ว่าจะมีข้อผิดพลาดเกิดขึ้นหรือไม่ก็ตาม (เช่น การปิด connection)
การเลือกใช้ Object-Oriented หรือ Procedural Style
MySQLi extension รองรับทั้ง Object-Oriented และ Procedural styles ซึ่งแต่ละ style ก็มีข้อดีข้อเสียที่แตกต่างกัน:
- Object-Oriented Style: ใช้ class และ object ในการจัดการการเชื่อมต่อและ query ฐานข้อมูล ข้อดีคือโค้ดมีความเป็นระเบียบและง่ายต่อการ reuse ข้อเสียคืออาจต้องใช้ความรู้ความเข้าใจเกี่ยวกับ OOP ในระดับหนึ่ง
- Procedural Style: ใช้ฟังก์ชันในการจัดการการเชื่อมต่อและ query ฐานข้อมูล ข้อดีคือเขียนง่ายและเข้าใจง่าย เหมาะสำหรับโปรเจกต์ขนาดเล็ก ข้อเสียคือโค้ดอาจไม่เป็นระเบียบและยากต่อการ reuse
ตัวอย่างโค้ดข้างต้นที่เราได้เห็นไปแล้วเป็นการใช้ Object-Oriented style หากเราต้องการใช้ Procedural style เราสามารถเขียนโค้ดได้ดังนี้:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$database = "database_name";
// สร้าง connection
$conn = mysqli_connect($servername, $username, $password, $database);
// ตรวจสอบ connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
mysqli_close($conn);
?>
คำอธิบายโค้ด:
$conn = mysqli_connect($servername, $username, $password, $database);: เป็นการสร้าง connection โดยใช้ฟังก์ชันmysqli_connect()if (!$conn) { ... }: เป็นการตรวจสอบว่าการเชื่อมต่อสำเร็จหรือไม่ หากเกิดข้อผิดพลาด จะแสดงข้อความผิดพลาดโดยใช้ฟังก์ชันmysqli_connect_error()และหยุดการทำงานของ script ด้วยdie()mysqli_close($conn);: เป็นการปิด connection เมื่อเราใช้งานเสร็จแล้ว
การตัดสินใจเลือก: การเลือกใช้ Object-Oriented หรือ Procedural style ขึ้นอยู่กับความถนัดและลักษณะของโปรเจกต์ หากโปรเจกต์มีขนาดใหญ่และซับซ้อน การใช้ Object-Oriented style จะช่วยให้โค้ดมีความเป็นระเบียบและง่ายต่อการบำรุงรักษา แต่หากโปรเจกต์มีขนาดเล็กและต้องการความรวดเร็วในการพัฒนา การใช้ Procedural style ก็อาจเป็นทางเลือกที่ดีกว่า
ในบทนี้ เราได้เรียนรู้วิธีการเชื่อมต่อกับฐานข้อมูล MySQL ด้วย MySQLi extension ทั้งในรูปแบบ Object-Oriented และ Procedural styles รวมถึงวิธีการตรวจสอบและจัดการ connection error ในบทถัดไป เราจะเรียนรู้เกี่ยวกับการ query ฐานข้อมูล (SELECT, INSERT, UPDATE, DELETE) ซึ่งเป็นขั้นตอนสำคัญในการดึงและจัดการข้อมูลในฐานข้อมูล