DataTables:server-side processing ตอน ดึงข้อมูลจากฐานข้อมูลมาแสดง

By -

DataTables server-side processing : แสดงข้อมูลจากฐานข้อมูล ด้วย datatable
หากจะมีคำถามว่า ทำไม ต้องมาสร้างกันละคนหน้า สร้างหน้าเดียวกัน ที่เรียกใช้ แล้ว select ทั้งหมด ออกมาเลยไม่ได้หรอ
เพราะยังไง datatable มันก็แบ่งหน้าให้อยุ่แล้ว.. คำตอบคือ ได้ครับ แต่ ถ้ามีข้อมูลซัก หนึ่ง แสน เร็คคอร์ด เวลา คิวรี่มันจะโหลด แบบเป็นชาติเลยสิครับ….
เนื่องจากปัญหาดังกล่าว datatable มันถึงมีไอ้เจ้า server side process นี่หล่ะ
ก็คือ การทำงานจากฝั่งเซอร์เวอร์นั่นเอง เอาง่ายๆ มันไม่ได้ดึงข้อมูลออกมาทั้งหมด มันดึงมาครั้งละ 10 50 หรือว่า 100 เร็คคอร์ด ตามที่เรากำหนดไว้ในหน้าแสดงข้อมูล
และเมื่อผุ้ใช้ เปลี่ยน เป็น show 50 entries มันก็ส่งค่าไปดึงมา 50 ถ้ามันทำงานแบบนี้ คุณคิดว่าดีไหมหล่ะ
เอาละมาเริ่มกันดีกว่า

สร้างฐานข้อมูลขึ้นมา เขียนโค้ด ( มีแถมในไฟล์ดาวน์โหลดด้านล่างครับ นะครับ )

DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
  `id` int(11) NOT NULL auto_increment,
  `iso` char(2) NOT NULL,
  `name` varchar(80) NOT NULL,
  `printable_name` varchar(80) NOT NULL,
  `iso3` char(3) default NULL,
  `numcode` smallint(6) default NULL,
  PRIMARY KEY  (`id`)
);

สร้างหน้า server_side.php ขึ้นมา เขียนโค้ด

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
		<link rel="shortcut icon" type="image/ico" href="http://www.datatables.net/media/images/favicon.ico" />
		
		<title>DataTables example</title>
       <!-- นำเข้าสคริปที่เกี่ยวข้อง-->
        
		<style type="text/css" title="currentStyle">
			@import "media/css/demo_page.css";
			@import "media/css/demo_table.css";
		</style>
		<script type="text/javascript" language="javascript" src="media/js/jquery.js"></script>
		<script type="text/javascript" language="javascript" src="media/js/jquery.dataTables.js"></script>
		<script type="text/javascript" charset="utf-8">
			$(document).ready(function() {
				$('#example').dataTable( {  // เขียนโค้ด โดยระบุให้ ไปดึงข้อมูลจาก ไฟล์ server_processing.php ที่อยุ่ในโฟลเดอร์ scripts มาทำงาน 
					"bProcessing": true,    // โดยเอาข้อมูลที่ได้มาแสดง ใน table ที่มี ไอดี เท่ากับ example
					"bServerSide": true,
					"sAjaxSource": "scripts/server_processing.php"
				} );
			} );
		</script>
	</head>
	<body id="dt_example">
		<div id="container">
			<div class="full_width big">
				DataTables server-side processing Tutorialdev.com</div>
			
			<h1>&nbsp;</h1>
<h1>Live example</h1>
			<div id="dynamic">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="example">
	<thead>
		<tr>
			<th width="20%">id</th>
			<th width="25%">iso</th>
			<th width="25%">name</th>
			<th width="15%">iso3</th>
			<th width="15%">numcode</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td colspan="6" class="dataTables_empty">Loading data from server</td>
		</tr>
	</tbody>
	<tfoot>
		<th width="20%">id</th>
			<th width="25%">iso</th>
			<th width="25%">name</th>
			<th width="15%">iso3</th>
			<th width="15%">numcode</th>
	</tfoot>
</table>
			</div>
			<div class="spacer"></div>
		
		</div>
	</body>
</html>





การทำงานของหน้านี้คร่าวๆ ก็คือ ให้ datatable ดึงข้อมูลจาก ไฟล์ server_processing.php ที่อยุ่ในโฟลเดอร์ scripts มาทำงาน โดยเอาข้อมูลที่ได้มาแสดง ใน table ที่มี ไอดี เท่ากับ example

ต่อไปเขียนโค้ด …server_processing.php

<?php
	
	/* ตัวแปร แบบ array เก็บฟิวด์ใน ฐานข้อมูล ต้องตรงกัน กับ จำนวน columns ที่อยู่ในไฟล์ server_side.php ด้วย  
	 */
	$aColumns = array( 'id', 'iso', 'name', 'printable_name', 'iso3','numcode' ,);  
	
	/* กำหนด primary key ให้กับคอลัมน์ */
	$sIndexColumn = "id";
	
	/* ชื่อตาราง */
	$sTable = "country";
	
	/* ส่วนของการเชื่อมต่อฐานข้อมูล */
	$gaSql['user']       = "root";
	$gaSql['password']   = "1234";
	$gaSql['db']         = "country";
	$gaSql['server']     = "localhost";
	
	/* ถ้าเกิดต้องการนำเข้าแบบไฟล์ ก็ต้อง ปิดตรงส่วนการเชื่อมต่อด้านบน แล้วใช้ โค้ดด้านล่างนี้แทน  */
	//include( $_SERVER['DOCUMENT_ROOT']."/datatables/mysql.php" );
	
	

	/* 
	 * MySQL connection
	 */
	$gaSql['link'] =  mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password']  ) or
		die( 'Could not open connection to server' );
	
	mysql_select_db( $gaSql['db'], $gaSql['link'] ) or 
		die( 'Could not select database '. $gaSql['db'] );
	
	
	/* 
	 * แบ่งหน้า
	 */
	$sLimit = "";
	if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
	{
		$sLimit = "LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".
			mysql_real_escape_string( $_GET['iDisplayLength'] );
	}
	
	
	/*
	 * จัดเรียงลำดับ
	 */
	$sOrder = "";
	if ( isset( $_GET['iSortCol_0'] ) )
	{
		$sOrder = "ORDER BY  ";
		for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
		{
			if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
			{
				$sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
				 	".mysql_real_escape_string( $_GET['sSortDir_'.$i] ) .", ";
			}
		}
		
		$sOrder = substr_replace( $sOrder, "", -2 );
		if ( $sOrder == "ORDER BY" )
		{
			$sOrder = "";
		}
	}
	
	
	$sWhere = "";
	if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" )
	{
		$sWhere = "WHERE (";
		for ( $i=0 ; $i<count($aColumns) ; $i++ )
		{
			$sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string( $_GET['sSearch'] )."%' OR ";
		}
		$sWhere = substr_replace( $sWhere, "", -3 );
		$sWhere .= ')';
	}
	
	/* เวลาค้นหาในคอลัมน์  */
	for ( $i=0 ; $i<count($aColumns) ; $i++ )
	{
		if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
		{
			if ( $sWhere == "" )
			{
				$sWhere = "WHERE ";
			}
			else
			{
				$sWhere .= " AND ";
			}
			$sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string($_GET['sSearch_'.$i])."%' ";
		}
	}
	
	
	/*
	 *คำสั่ง SQL ดึงข้อมูลออกมาโชว์
	 * 
	 */
	$sQuery = "
		SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
		FROM   $sTable
		$sWhere
		$sOrder
		$sLimit
	";
	$rResult = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
	
	/* จำนวนข้อมูลหลังจากค้นหา */
	$sQuery = "
		SELECT FOUND_ROWS()
	";
	$rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
	$aResultFilterTotal = mysql_fetch_array($rResultFilterTotal);
	$iFilteredTotal = $aResultFilterTotal[0];
	
	/*  จำนวนทั้งหมด */
	$sQuery = "
		SELECT COUNT(".$sIndexColumn.")
		FROM   $sTable
	";
	$rResultTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
	$aResultTotal = mysql_fetch_array($rResultTotal);
	$iTotal = $aResultTotal[0];
	
	
	/*
	 * ส่วนการแสดงผล
	 */
	$output = array(
		"sEcho" => intval($_GET['sEcho']),
		"iTotalRecords" => $iTotal,
		"iTotalDisplayRecords" => $iFilteredTotal,
		"aaData" => array()
	);
	
	
	
	while ( $aRow = mysql_fetch_array( $rResult ) )  //loop ออกมาแสดงข้อมูล 
	{
		$row = array();
		for ( $i=0 ; $i<count($aColumns) ; $i++ )
		{
			if ( $aColumns[$i] == "version" )
			{
				$row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
			}
			else if ( $aColumns[$i] != ' ' )
			{
				$row[] = $aRow[ $aColumns[$i] ];
			}
		}
		$output['aaData'][] = $row;
	}
	
	echo json_encode( $output );
?>


ส่วนการทำงานก็ รับค่าที่ถูกส่งมาจากหน้า server_side.php แล้วก็ดึงข้อมูลออกมาจากฐานข้อมูลตามเงื่อนไขต่างๆ ไม่ว่าจะเป็นค้นหา คลิกเลือกหน้า (ส่วนรายละเอียดผมคอมเมนต์ไว้ใน ไฟล์เลยนะครับ ขอข้ามไป) แล้วรีเทริน เป็น json กลับไป
view แสดงผลปกติ
server-side

ค้นหาข้อมูล
server-side-search

download

mitsumasa