แนวทางตรวจสอบ error การเชื่อมต่อ และการคิวรี่ข้อมูลจาก database

เขียนเมื่อ 5 ปีก่อน โดย Ninenik Narkdee
php errorrs mysql error

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ php errorrs mysql error

ดูแล้ว 44,579 ครั้ง


เนื้อหาต่อไปนี้ เราจะเป็นตัวอย่าง แนวทางการทดสอบ การเชื่อมต่อกับฐานข้อมูล 
กรณีเกิด error ในรูปแบบต่างๆ โดยเนื้อหานี้ จะเป็นการเพิ่มเติมจากความคิดเห็นใน ถาม-ตอบ
ตามลิ้งค์ด้านล่าง
 
 
สำหรับตัวอย่างฐานข้อมูลทดสอบ 
จะใช้ชื่อ 
username: root
password
database: test 
ทดสอบที่ localhost
* password เป็นค่าว่าง
 
ส่วนตารางฐานข้อมูลจะใช้ตัวอย่างจากลิ้งค์ด้านล่าง
 
 
เริ่มเต้น เราจะมี 2 ไฟล์ 
    - dbconnect.php
    - test_error.php
 

ไฟล์ dbconnect.php

 
<?php  
$mysqli = new mysqli("localhost", "root","","test");  
/* check connection */
if ($mysqli->connect_errno) {  
    printf("Connect failed: %s\n", $mysqli->connect_error);  
    exit();  
}  
if(!$mysqli->set_charset("utf8")) {  
    printf("Error loading character set utf8: %s\n", $mysqli->error);  
    exit();  
}
 

ไฟล์ test_error.php

 
<?php  
require_once("dbconnect.php");
 
 
สำหรับการทดสอบ error ของโค้ด เราต้องเช็คก่อนว่า มีการเปิดใช้งานการแจ้ง error อยู่แล้วหรือไม่ โดยสามารถกำหนด
ที่การตั้งค่า Configure ของไฟล์ PHP.ini 
 
display_errors = on
 
ถ้ามีการกำหนดค่าเป็น on แสดงว่าจะมีการแจ้ง error เมื่อเกิดข้อผิดพลาดหรือการแจ้งเตือนต่างๆในการทำงานของโค้ด
หากไม่ต้องการแสดง เราก็กำหนดเป็น off
 
หรือจะทดสอบง่าย โดยการเขียนโค้ดคำสั่ง ผิดพลาด เช่น
 
<?php
require_once("dbconnect_no_file.php");
 
หากแสดง error แจ้งเตือนในลักษณะคล้ายๆ กับด้านล่าง
 
Warning: require_once(dbconnect_no_file.php): failed to open stream: No such file or directory in C:\xampp\htdocs\demo\test_error.php on line 2

Fatal error: require_once(): Failed opening required 'dbconnect_no_file.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\demo\test_error.php on line 2
 
ก็แสดงว่า ระบบเปิดการใช้งาน การแจ้งเตือนข้อความ error อยู่
 
สังเกตว่า การแจ้งเตื่อนมีประโยชน์มากในขั้นตอนการพัฒนา เพราะทำให้เราทราบถึง ปัญหาหรือคำเตือนของโค้ดที่เรียกใช้งาน
อยู่ ทำให้เราทำความเข้าใจ และแก้ไขโค้ดได้ตรงจุด  แต่การแจ้งเตือน error นั้น ก็จะมีข้อควรระวัง กรณีนำไปใช้งาน
เช่นกัน เพราะในบางครั้ง มีการเปิดเผยข้อมูลบางอยาง ที่มีผลต่อความปลอดภัยของเว็บไซต์หรือโค้ดนั้นๆ ดังนั้น เมื่อมีการ
นำโค้ดไปใช้งาน เราควรปิดการแจ้งเตือน error เพื่อป้องกันกรณีดังกล่าว ทุกครั้ง หรือจะใช้วิธีจำกัดการแจ้งเตือน โดยกำหนด
รูปแบบหรือข้อความแจ้งเตือนเองก็ได้ 
 
อย่างในตัวอย่างไฟล์ dbconnect.php 
 
if ($mysqli->connect_errno) {  
    printf("Connect failed: %s\n", $mysqli->connect_error);  
    exit();  
}  
 
จะเห็นว่ามีการตรวจสอบ error และแจ้งเตือน ด้วยข้อความ Connect failed: และเพิ่มการแจ้งเตือนจากระบบ
ด้วย $mysqli->connect_error หากเราต้องการกำหนดการแจ้ง error ที่กำหนดเอง ก็ตัดในส่วนของการแจ้งเตือนของระบบ
ออกไปได้ ก็จะได้เป็น
 
if ($mysqli->connect_errno) {  
    printf("Connect failed: %s\n";  
    exit();  
}  
 
 
การปิดการแจ้งเตือน บางครั้งเราอาจจะไม่สามารถไปแก้ไขไฟล์ php.ini ได้ เราสามารถกำหนดผ่านไฟล์ .htacccess
โดยใช้ค่าดังต่อไปนี้
 
php_flag display_startup_errors on
php_flag display_errors on
 
เปลี่ยนค่าเป็น on หรือ off ตามต้องการ
 
และอีกวิธี คือเพิ่มโค้ด ต่อไปนี้ไว้ในส่วนด้านบนของไฟล์ 
กรณีเปิดการแสดงการแจ้งเตือน
 
/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
 
หรือปิดการแจ้งเตือน
 
/** Error reporting */
error_reporting(0);
ini_set('display_errors', FALSE);
ini_set('display_startup_errors', FALSE);
 
ตัวอย่าง
 
<?php
/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
require_once("dbconnect.php");
 
หรือจะสร้างเป็นไฟล์ report_error.php ไว้ เรียกใช้งานโดยการ include ไฟล์มาก็ได้
 

ไฟล์ report_error.php

 
<?php
/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
/*error_reporting(0);
ini_set('display_errors', FALSE);
ini_set('display_startup_errors', FALSE);*/
 
การเรียกใช้งาน
 
<?php
include_once("report_error.php");
require_once("dbconnect.php");
 
 
ส่วนการกำหนดการแจ้ง error เพิ่มเติม สามารถดูแนวทางได้ที่
 
 
กลับมาที่การแจ้งเตือนการเชื่อมต่อกับฐานข้อมูลของเรา
สมมติเรากำหนด ชื่อ database ผิด และ กำหนด ชื่อผู้ใช้ หรือรหัผสผ่านผิด จะแจ้ง error ตามข้อความด้านล่าง ตามลำดับ
 
Warning: mysqli::__construct(): (HY000/1049): Unknown database 'test1' in C:\xampp\htdocs\demo\dbconnect.php on line 2
Connect failed: Unknown database 'test1'

Warning: mysqli::__construct(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES) in C:\xampp\htdocs\demo\dbconnect.php on line 2
Connect failed: Access denied for user 'root'@'localhost' (using password: YES)
 
ต่อไปเราจะจำลองเหตุการณ์ error ในกรณีต่างๆ เกี่ยวกับการใช้งานร่วมกับ database
 

แบบที่ 1

 

ไฟล์ test_error.php

 
<?php
include_once("report_error.php");
require_once("dbconnect.php");

$sql = "
SELECT * FROM tbl_doc
";
$result = $mysqli->query($sql2);
$row = $result->fetch_assoc();
echo $row['user_v5'];
?>
 
สมมติว่า tbl_doc เป็นตาราง ที่ไม่มีรายการข้อมูล 
เรามาดู error และการ เตื่อน 
 
Notice: Undefined variable: sql2 in C:\xampp\htdocs\demo\test_error.php on line 8

Warning: mysqli::query(): Empty query in C:\xampp\htdocs\demo\test_error.php on line 8

Fatal error: Uncaught Error: Call to a member function fetch_assoc() on boolean in C:\xampp\htdocs\demo\test_error.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\demo\test_error.php on line 9
 
Notice: แจ้งจุดสังเกต ที่ต้องตรวจสอบ จะเห็นว่า เราเรียกใช้ตัวแปร ที่ไม่ได้กำหนด คือ เรียกใช้ $sql2 แทนที่จะเป็น $sql
ส่งผลต่อให้ $mysqli->query() ทำงานไม่ได้ แจ้ง เตือน Warning 
ถึงจุดนี้ ก็ส่งผลต่อ ตัวแปร $result เป็น false 
และในบรรทัดที่ 9 เราก็เรียกใช้งาน $result ทั้งที่เป็น false โดยเรียกใช้งานผ่าน $result->fetch_assoc(); จึงเกิด error
 
เราแก้ไข และเพิ่มการตรวจสอบเข้าไปเป็น ดังนี้
 
$sql = "
SELECT * FROM tbl_doc
";
$result = $mysqli->query($sql);
if($result){
	$row = $result->fetch_assoc();
	echo $row['user_v5'];
}
 
จะเห็นว่าตรวจสอบค่า $result โดยใช้ if($result) คือถ้ามีค่านี้ และไม่เท่ากับ false
เราสามารถตรวจสอบค่า เพิ่มเติม โดยเรียกใช้ var_dump()
 
if($result){
	var_dump($result);
	$row = $result->fetch_assoc();
	echo $row['user_v5'];
}
 
เพื่อดูข้อมูลหรือโครงสร้างของ $result
 
จากรูปแบบการแก้ปัญหาข้างต้น ก็จะไม่มีรายการแจ้งเตือนใดๆ และก็ไม่มีข้อมูลแสดง เนื่องจากตารางที่เราทดสอบ
มีแค่ตาราง แต่ไม่มีข้อมูล
 
 
 

แบบที่ 2

 
ถ้าเราสมมติให้คำสั่ง sql ไม่ถูกต้อง เช่น ไม่มีตารางข้อมูลนั้น ยกตัวอย่างเปลี่ยน tbl_doc เป็น tbl_doc2
ผลที่ได้คือ $result จะเป็น false หากต้องการตรวจสอบ โดยให้แจ้งเตือน เราอาจจะเพิ่มในลักษณะแบบนี้เข้าไป
 
$sql = "
SELECT * FROM tbl_doc2
";
$result = $mysqli->query($sql);
if($result){
	$row = $result->fetch_assoc();
}else{
	die("Error : ".$mysqli->error."<br/>SQL :".$sql);
}
 
หรือ
 
$sql = "
SELECT * FROM tbl_doc2
";
$result = $mysqli->query($sql) or die("Error : ".$mysqli->error."<br/>SQL :".$sql);
if($result){
	$row = $result->fetch_assoc();
}
 
ในที่นี้ เราจะใช้รูปแบบหลัง ผลที่ได้ จะขึ้น error ดังนี้
 
Error : Table 'test.tbl_doc2' doesn't exist
SQL : SELECT * FROM tbl_doc2
 
จะเห็นว่า ส่วนของ error จะเป็นการแจ้งเตือน ว่าเกิดข้อผิดพลาดส่วนไหน ทำให้เราสามารถนำไปเป็นแนวทางในการ
แก้ไขได้ ส่วนคำสั่ง SQL ด้านล่าง ใช้ทบทวน ว่า คำสั่ง SQL ที่ถูกนำไปคิวรี่ เป็นแบบไหน มีจุดต้องแก้ไข หรือเปรียบ
เทียบ หรือตรวจทาน
 
ลองอีกเงื่อนไข สมมติเรากำหนดชื่อฟิลด์ ที่เรียกใช้งานไม่ถูกต้องเป็นดังนี้
 
$sql = "
SELECT province_i FROM tbl_provinces
";
 
เราเรียก province_i แทนที่จะเป็น province_id ก็จะขึ้น error แจ้งดังนี้
 
Error : Unknown column 'province_i' in 'field list'
SQL : SELECT province_i FROM tbl_provinces
 
ลองอีกเงื่อนไขดังนี้
 
$sql = "
SELECT province_iก FROM tbl_provinces WHERE 
";
 
ก็จะขึ้น error แจ้ง รูปแบบคำสั่ง SQL ไม่ถูกต้อง
 
Error : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
SQL : SELECT province_iก FROM tbl_provinces WHERE
 
ลองอีกเงื่อนไข
 
$sql = "
SELECT id_a FROM tbl_a,tbl_b WHERE id_a>0 
";
 
รูปแบบข้างต้น เป็นการเรียก ตาราง 2 ตารางมาแสดง 
tbl_a จะมีฟิลด์ id_a , user_a และ number_a
tbl_b จะมีฟิลด์ id_b, id_a และ pass_b
 
error จากการเรียกใช้ข้างต้น
 
Error : Column 'id_a' in field list is ambiguous
SQL : SELECT id_a FROM tbl_a,tbl_b WHERE id_a>0
 
มีการแจ้งว่า ใช้ id_a ไม่ชัดเจน กำกวม ไม่เฉพาะเจาะจง ทั้งนี้ก็เพราะว่า id_a เป็นฟิลด์ที่อยู่ในทั้ง 2 ตาราง
การกำหนดว่า id_a>0 จึงไม่ชัดเจนว่า id_a ของตารางใด ดั้งนั้นจำไว้เสมอว่า หากมีการเรียกใช้ตาราง
พร้อมกันหลายตาราง ให้ระบุชื่อตาราง หรือชื่อเรียกแบบย่อเพิ่มเข้าไปด้วย ว่าเป็นฟิลด์ของตารางไหน เช่น
 
$sql = "
SELECT tbl_a.id_a FROM tbl_a,tbl_b WHERE tbl_a.id_a>0 
";
 
หรือจะใช้ชื่อย่อแทน เพื่อให้เขียนสั้นลงได้ เช่น
 
$sql = "
SELECT a.id_a FROM 
tbl_a a,
tbl_b b 
WHERE a.id_a>0 
";
 
แบบนี้เป็นต้น
 
 
หมายเหตุ: การแจ้ง คำเตือน หรือข้อผิดพลาด ของ php จะเป็นคนละส่วนของ การเรียกใช้งาน $mysqli->error 
นั่นหมายความว่า หากคำสั่ง php ไม่เกิดข้อผิดพลาดใดๆ ขึ้นเลย แต่คำสั่ง sql เกิดข้อผิดพลาดขึ้น ถึงจะปิดการแสดง
error แต่ส่วนของ $mysqi->error ก็จะยังแสดงข้อมูล
แต่ถ้าหากว่า ตัวโค้ด php มีข้อผิดพลาด และเราปิดการแสดงข้อผิดพลาด คำสั่ง $mysqi->error ก็จะไม่ทำงานด้วย
 
$sql = "
SELECT province_i FROM tbl_provinces  
";
$result = $mysqli->query($sql2) or die("Error : ".$mysqli->error."<br/>SQL :".$sql);
if($result){
	$row = $result->fetch_assoc();
}
 
อย่างกรณีตามโค้ดด้านบน เมื่อเราปิดการแจ้งเตือน error แล้วเรียกคำสั่ง SQL ผ่านตัวแปร $sql2 แทนที่จะเป็น $sql
ผลที่ได้ก็จะแสดงเป็น
 
Error : 
SQL : SELECT province_i FROM tbl_provinces
 
จะเห็นว่า ไม่ขึ้นแจ้งเตือนใดๆ และส่วนของ $mysqli->error ก็ไม่ทำงาน และไม่แสดงแจ้ง error
 
แต่ถ้าเราเปลี่ยนจาก $sql2 เป็น $sql ผลที่ได้ จะเป็นดังนี้
 
Error : Unknown column 'province_i' in 'field list'
SQL : SELECT province_i FROM tbl_provinces
 
ทั้งนี้เพราะ คำสั่ง $mysqli->error จะแสดงปกติ ถึงแม้จะปิดการแจ้งเตือน 
 


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ







เนื้อหาที่เกี่ยวข้อง









URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ