หลังจากบทที่แล้วเราติดตั้งฐานข้อมูล MySQL เสร็จเรียบร้อยแล้ว และทำให้ใช้งานร่วมกับ PHP ได้แล้ว ทีนี้เราจะเริ่มใช้งานมันได้ยังไง เดี๋ยวมาดูกันครับ

การติดต่อ MySQL จาก PHP จากที่เคยทำมามันก็มี 2 วิธีหลักๆ คือ ติดต่อโดยตรงโดยผ่าน Native Driver ที่มาพร้อมกับ PHP เลย กับอีกวิธีคือใช้ PDO (PHP Data Object) จริงๆ ผมไม่อยากเรียก PDO ว่าเป็น Native Driver เท่าไหร่ เพราะมันติดต่อฐานข้อมูลได้หลายแบบเหลือเกิน แต่ในเว๊ปของ MySQL บอกไว้แบบนั้นงะ

ลำดับการทำงานของทั้งสองขั้นตอนจะคล้ายๆ กันคือ

      สร้างการเชื่อมต่อกับ MySQL
      ติดต่อกับฐานข้อมูลที่จะใช้งาน
      ปิดการเชื่อมต่อกับ MySQL

ผมจะอธิบายรายละเอียดเฉพาะแบบแรกนะครับ ส่วนแบบที่สองจะให้ตัวอย่างแล้วอธิบายนิดหน่อย เพราะถ้าเข้าใจเรื่อง OOP แล้ว PDO มันไม่ยากเลย บางทีอ่านแค่ Class กับ Method ก็เอาไปใช้งานได้แหละ อีกอย่างเซิร์ฟเวอร์ที่เราเช่าบางทีไม่เปิดใช้งาน PDO ก็มี แอบเศร้าเลย

ขั้นตอนที่ 1 เชื่อมต่อฐานข้อมูล

ทำได้โดยใช้ฟังก์ชั่น mysql_connect โดยค่าทีต้องส่งจะมีสามค่าคือ

  • string Host (IP ของ MySQL ในกรณีที่อยู่ในเครื่องเดียวกันให้ใส่ localhost)
  • string MySQL username
  • string MySQL password

เขียนได้ตามตัวอย่างนี้

<?php
   mysql_connect("host", "mysql_username", "mysql_password");
?>

ขั้นตอนที่ 2 ติดต่อกับฐานข้อมูลที่เราจะใช้งาน

โดยใช้คำสั่ง mysql_select_db โดยมีค่าที่ต้องใ่ส่คือ

  • string ชื่อฐานข้อมูล
  • link identifier (จะใส่หรือไม่ใส่ก็ได้)

เขียนได้ตามตัวอย่างนี้

<?php
   mysql_select_db("database", [$link]);
?>

ขอเน้นนิดนึง

ตรงที่ผมเขียนว่า $link ผมใส่ bucket ไว้หมายความว่า จะใส่หรือไม่ใส่ก็ได้ ใส่แล้วมันก็ไม่ได้ทำงานเร็วขึ้นหรือดีขึ้น แต่ผมแนะนำให้ใส่ทุกครั้ง และให้ทำจนเป็นนิสัยเลย… ทำไมอ่า เมื่อกี้ยังบอกว่า “ไม่ใส่ก็ได้” เลย คืองี้ครับ ถ้าหากเราทำงานกับฐานข้อมูลหลายๆ ตัว และอยู่คนละโฮส เอาง่ายๆ ถ้าต้องการติดต่อฐานข้อมูลในเครื่องเรา และเครื่องที่ทำงาน เราต้องเขียนการเชื่อมต่อสองครั้ง แล้วถ้าเราต้องการ query ล่ะ จะรู้ได้ไงว่าเอามาจากไหน มันก็เลยต้องมีตัวเชื่อมต่อเพื่อบอกว่าเราจะเอาจากเครื่องของเรา หรือจากเครื่องที่ทำงานไงครับ…

แต่ถ้าเกิดเหตุการณ์ที่ต้องเอาฐานข้อมูลจากสองที่คนละโฮส เมื่อก่อนผมก็ทำแบบที่ผมว่าข้างบน แต่เดี๋ยวนี้เขียน XML นิดๆ หน่อยๆ สะดวกกว่าครับ อาจไม่เร็วเท่าต่อโดยตรง แต่ปลอดภัยกว่า

ขั้นตอนที่ 3 ปิดการเชื่อมต่อ

ในเมื่อมีการเชื่อมต่อแล้วก็ต้องทำการปิดการเชื่อมต่อด้วยสิ ถ้าหากรอ session ใน MySQL หมดแล้วให้มันตัดการเชื่อมต่อเองเดี๋ยวหน่วยความจำของเซิร์ฟเวอร์จะหมดเกลี้ยงเสียก่อน ถ้าหากเราใช้งานแค่คนเดียวก็ไม่เท่าไหร่ แต่เข้ามาสัก 1000 คน 1000 connections 1000 processes ถ้าไม่คืนหน่วยความจำให้หลังจากใช้งานเสร็จหน่วยความจำเท่าไหร่ก็ไม่พออ่ะครับ วิธีการคืนหน่วยความจำก็ง่ายๆ เลย

<?php
   mysql_close([$link]);
?>

ผมใส่ bucket อีกแล้ว คำสั่งนี้จะมีตัวที่เชื่อมต่อส่งเข้าไปด้วยหรือไม่ก็ได้ ถ้าหากเราส่งตัวเชื่อมต่อเข้าไป มันก็จะปิดตัวเชื่อมต่อตัวนั้น แต่ถ้าไม่ใส่เข้าไป มันจะปิดตัวเชื่อมต่อตัวล่าสุดที่ทำการสร้างการเชื่อมต่อ … งง ไหมเนี่ย เอาเป็นว่า อย่างที่บอกอ่ะครับ ควรกำหนดตัวเชื่อมต่อให้เป็นนิัสัยเลย เวลาปิดจะได้กำหนดไปเลยว่าจะปิดตัวไหน

ทีนี้ลองเอามาใช้งานจริงกัน

ในฐานข้อมูล MySQL จะมีฐานข้อมูลชื่อ mysql อยู่แล้ว เราก็ลองเรียกดูข้อมูลผ่าน PHP ล่ะกัน แต่ อย่าไปแก้ไขอะไรมันนะครับ เดี๋ยวเจ้งเอา

<?php
   $connect = mysql_connect("localhost", "root", "cmdevhub") or die("ติดต่อ MySQL ไม่ได้"); // เก็บการเชื่อมต่อไว้ที่ตัวแปร $connect
   mysql_select_db("mysql", $connect) or die("ติดต่อฐานข้อมูลไม่ได้"); // ทำการติดต่อฐานข้อมูล

   $SQLCom = "select * from user"; // สร้างคำสั่ง SQL เก็บไว้ในตัวแปรชื่อ $SQLCom
   $query = mysql_query($SQLCom, $connect); // ทำการคิวรี่
   $rs = mysql_fetch_assoc($query); // เอาออกมาแค่แถวเดียวก็พอ
   print_r($rs); // พิมพ์ออกหน้าจอ
   mysql_close($connect); // ปิดการเชื่อมต่อ
?>

ผลลัพท์ที่ได้ก็จะเป็นแบบนี้

ถ้าหากได้ผลลัพท์ประมาณนี้แสดงว่าคุณเชื่อมต่อกับฐานข้อมูลได้แล้วและพร้อมจะเขียนโปรแกรมที่ใช้งานจริงได้แล้วทันที (ง่ายไหม) ส่วนคำสั่งอื่นๆ ยังไม่ต้องสนใจครับ เอาไว้มาคุยรายละเอียดกันทีหลัง

การเชื่อมต่อฐานข้อมูลเราต้องทำการเชื่อมต่อทุกครั้งในทุกๆ หน้าที่มีการเชื่อมต่อกับฐานข้อมูล (งงไหมเนี่ย) ตีความง่ายๆ คือ ถ้าหากมีไฟล์ในเว๊ปของเรา 100 ไฟล์ เราก็ต้องเขียนการเชื่อมต่อทั้ง 100 ไฟล์เลย เราขยันอยู่แล้ว ไม่ใช่ปัญหา แต่ปัญหาจะเกิดขึ้นทันทีเมื่อ เราเอางานของเราไปไว้ที่อื่น ตัวอย่างง่ายๆ ก็คือการอัพโหลไปไว้ในโฮส แน่นอนฐานข้อมูลต้องไม่ใช่ชื่อเดิม username และ password ก็ต้องเปลี่ยน ทีนี้เราก็ต้องไล่เปลี่ยนทั้ง 100 ไฟล์เลย สนุกสนานแน่นอน…

เพราะงั้นเรามาทำให้ชีวิตเราง่ายขึ้นดีกว่า จาก บทที่ 8 เรื่องฟังก์ชั่น (ดูจากข้างๆ หรือจิ้มที่ลิงค์เลย) เราสามารถเขียนฟังก์ชั่นครั้งเดียวแล้วเรียกใช้กี่ทีก็ได้ โอ้ว ทำไมช่างสะดวกเช่นนี้

ผมจะใช้วิธีสร้างไฟล์ขึ้นมาไฟล์หนึ่งเก็บฟังก์ชั่นไว้แล้วถ้าต้องการติดต่อฐานข้อมูลก็แค่ include เข้าไป (จะใช้ require ก็ได้ไม่ว่ากัน) จากนั้นก็เรียกฟังก์ชั่นติดต่อฐานข้อมูลเอา เท่านี้ก็เสร็จแล้ว ตัวอย่างตามนี้เลยครับ

<?php
   // ไฟล์ชื่อ function.inc.php

   function connect() {
      global $connect;
      $connect = mysql_connect("localhost", "root", "cmdevhub") or die("ติดต่อ MySQL ไม่ได้");
      mysql_select_db("mysql", $connect) or die("ติดต่อฐานข้อมูลไม่ได้");
   }

   function disconnect() {
      global $connect;
      mysql_close($connect);
   }
?>

ไฟล์ function.inc.php สร้างไว้สำหรับ include อย่างเดียว มี 2 ฟังก์ชั้นคือ connect() และ disconnect()

<?php
   // ไฟล์ชื่อ testmysql.php

   require_once('function.inc.php'); // อย่าลืมเอาไฟล์นี้ไว้ที่เดียวกันนะครับ
   connect();
   $SQLCom = "select * from user";
   $query = mysql_query($SQLCom, $connect);
   $rs = mysql_fetch_assoc($query);
   print_r($rs);
   disconnect();
?>

ผลลัพท์ที่ได้ก็เหมือนเดิมทุกอย่าง แต่ถ้าเราย้ายโฮสปุ๊ป ก็แค่ไปแก้ไข username และ password ในไฟล์ function.inc.php เท่านั้นเอง ไฟล์อื่นๆ เราไม่ต้องไปยุ่งอะไรกับมันเลย ชีวิตสบายขึ้นอีกเยอะเลย หุหุ

ทำให้ดูเป็นมืออาชีพขึ้นหน่อยไหม

ในเมื่อ PHP สามารถเขียนเป็น OO ได้ (Object Oriented) ทำไมเราจะไม่เขียนให้มันเป็น OO หน่อยล่ะ หุหุ (เนื่องจากมันไม่มีอะไรมาก ผมไม่เอา Class Diagram ลงเนอะ มีแค่ 2 Class เอง)

เพื่อให้ (ดูเหมือน) เป็นมืออาชีพ เวลาผมเขียนโปรแกรมผมชอบที่จะแยกไฟล์สำหรับเก็บ Constant Variable, Class ไว้แยกกัน ก็เอาตามนี้เลยครับ

<?php
   // ไฟล์ชื่อ user.inc.php

   define("DBHOST", "localhost");
   define("DBUSER", "root");
   define("DBPASS", "cmdevhub");
   define("DBNAME", "mysql");
?>
<?php
   // ไฟล์ชื่อ class.inc.php

   require_once("user.inc.php");

   class mysql {
      private $connect;
      private $query;
      private $result;

      public function connect() {
         if(!$this->connect = mysql_connect(DBHOST, DBUSER, DBPASS)) {
            echo get_class($this) . "::connect() Error Connect MySQL " . mysql_error();
            return false;
         }
         else {
            if(!mysql_select_db(DBNAME, $this->connect)) {
               echo get_class($this) . "::connect Error Select Database " . mysql_error();
               mysql_query("set names utf8", $this->connect);
            }
         }
      }

      public function query($command) {
         if (!$this->connect) {
            $this->connect();
         }
         if (!$this->query = mysql_query($command, $this->connect)) {
            echo get_class($this) . "::query() SQL Command invalid " . mysql_error();
         }
         else {
            return $this->query;
         }
      }

      public function fetch_assoc($query = '') {
         if ($query == NULL) {
            $result = mysql_fetch_assoc($this->query);
         }
         else {
            $result = mysql_fetch_assoc($query);
         }

         if (is_null($result)) {
            echo get_class($this) . "::fetch_assoc() Error fetch result";
         }
         else {
            return $result;
         }
      }

      public function num_rows($query = '') {
         if ($query == NULL) {
            return mysql_num_rows($this->query);
         }
         else {
            return mysql_num_rows($query);
         }
      }

      function __destruct() {
         if($this->connect) {
            mysql_close($this->connect);
         }
      }
   }
?>

ไฟล์นี้ผมไม่ขออธิบายเนอะ ไว้ค่อยคุยกันวันหลัง แต่เป็นการเชื่อมต่อฐานข้อมูลที่ผมใช้งานจริงๆ อยู่อ่ะ (เอาไปใช้ได้นะ)

วิธีการใช้งานก็ง่ายๆ แบบนี้เลยครับ

<?php
   require_once("class.inc.php");

   $mysql = new mysql();
   $SQLCom = "select * from user";
   $mysql->query($SQLCom);
   $rs = $mysql->fetch_assoc();
   print_r($rs);
?>

ง่ายใช่ไหมครับ ตอนนี้เราโยนทุกอย่างให้เป็นหน้าที่ของคลาส mysql ส่งคำสั่งไปคิวรี่โดยไม่ต้องสร้างการเชื่อมต่อ โดยเมธอด query จะทำการตรวจสอบเองว่ามีการสร้างการเชื่อมต่อมาแล้วหรือยัง แล้วพอจบหน้าก็ไม่ต้องทำการตัดการเชื่อมต่อ destructor จะตัดการเชื่อมต่อเองโดยอัตโนมัติ (สบายเลย)

Comments

จำนวนความเห็น