Codeigniter ตอน pagination class

Codeiginer มี pagination class เพื่อช่วยในการจัดแบ่งข้อมูลที่จะนำแสดงบนเว็บ โดยผู้ใช้สามารถกำหนดได้ว่าในแต่ละหน้านั้น จะให้แสดงจำนวนข้อมูลจำนวนเท่าใด โดยจะมีการทำลิ้งก์ให้เลือกหน้าถัดไปหรือย้อนหลังให้อัตโนมัติ เช่น

« First < 1 2 3 4 5 > Last »

ตัวอย่างการใช้งาน

$this->load->library('pagination');

$config['base_url'] = 'http://example.com/index.php/test/page/';
$config['total_rows'] = '200';
$config['per_page'] = '20';

$this->pagination->initialize($config);

echo $this->pagination->create_links();

องค์ประกอบเบื้องต้น
ตัวแปร  $config จากตัวอย่างข้างต้น  ใช้ในการกำหนดองค์ประกอบที่ต้องการ  โดยสามารถสร้างไฟล์สำหรับเก็บตัวแปร $config ชื่อ  pagination.php  แยกไว้ต่างหาก   แล้วบันทึกไฟล์ไว้ที่ config/pagination.php

  • base_url เป็น URL ของ controller class  และ function ของเพจที่เราต้องการแบ่งการแสดงผลเป็นหน้า  ซึ่งจะต้องกำหนดค่าให้ถูกต้อง  เพราะเวลาเปลี่ยนหน้านั้นจะมีการส่งค่าให้ function  เพื่อนำไป query ข้อมูลจากฐานข้อมูล
  • total_rows เป็นจำนวนข้อมูลทั้งหมดที่เราต้องการนำมาแบ่งการแสดงผลเป็นหน้า  จากตัวอย่างข้างต้นเป็นการกำหนดข้อมูลให้มีค่าเป็น 200   แต่ในการใช้งานจริงนั้น จำนวนข้อมูลทั้งหมดจะเป็นจำนวน record ที่ได้มาจากการ query ข้อมูลจากฐานข้อมูล
  • per_page เป็นการกำหนดจำนวนข้อมูลที่จะให้แสดงในแต่ละหน้า
  • initialize() เป็นฟังก์ชันส่งตัวแปร $config ให้ pagination class  เพื่อให้จัดองค์ประกอบอย่างที่เราต้องการ
  • create_links()  เป็นฟังก์ชันที่สร้างลิ้งก์เลือกหน้าให้เราโดยอัตโนมัติ

ในการใช้งานจริงนั้น ส่วนของ base_url  เราสามารถใช้ฟังก์ชัน base_url()  ของ  URL helper มาช่วยได้ เช่น

$config['base_url'] =  base_url().'/controller/function';

และสำหรับจำนวนข้อมูลทั้งหมดนั้น สามารถใช้ฟังก์ชัน count_all() ของ  Active record class มาช่วยนับจำนวน record ทั้งหมดในตารางได้ เช่น

$config['total_rows'] = $this->db->count_all('table');

สำหรับในกรณีที่ต้องการจำนวน record ที่ได้จากคำสั่ง query  สามารถใช้ฟังก์ชัน count_all_results() ของ   Active record class หรือฟังก์ชัน  num_rows()  จาก Result helper class ช่วยหาข้อมูลได้

ตัวอย่างการใช้ pagination class ใน controller มีดังนี้

function showdata()
{
	// Pagination section
	$config['base_url'] =  base_url().'/controller/showdata';
	$config['total_rows'] = $this->db->count_all('data_table');
	$config['per_page'] = '10';

	$this->pagination->initialize($config);
	$pagination_link = $this->pagination->create_links();
        // Send pagination link to Smarty
	$this->cismarty->assign('pagination_link', $pagination_link);

	// Get data from my_model
	$data = $this->my_model->get_data( $config['per_page'], $this->uri->segment(3) );
	$this->cismarty->assign('data', $data);

	// Output to browser
	$this->cismarty->display('showdata.tpl');
}

จากตัวอย่างข้างต้น  จะเห็นฟังก์ชัน get_data()  ต้องการ 2 อาร์กิวเม้นต์คือ $config[‘per_page’]  และ $this->uri->segment(3)

  • $config[‘per_page’]  ใช้สำหรับกำหนดจำนวนข้อมูลที่ต้องการให้แสดงในแต่ละหน้า  ดังที่อธิบายไว้ข้างต้น  ซึ่งจะถูกใช้เป็นค่าของ limit ในการ query ข้อมูล
  • $this->uri->segment(3)  เป็นการอ้างถึงค่าของ segment ที่ 3 ใน URL   เช่น เลข 5  ใน URL ต่อไปนี้  http://www.domain.com/controller/showdata/5  เป็นค่าที่อยู่ใน segment ที่ 3  ซึ่งจะถูกใช้เป็นค่า offset ในการ query ข้อมูล

ตัวอย่างฟังก์ชัน get_data() ของ my_model มีดังนี้

function get_data($per_page, $offset)
{

	$this->db->from('data_table');
	$this->db->limit($per_page, $offset);
	$query = $this->db->get();
	$data = $query->result_array();

        // Other code here ...
}

เทียบได้กับการใช้คำสั่ง  SELECT * FROM data_table  LIMIT  $per_page, $offset
($this->db->limit() เป็นฟังก์ชันของ Active record class)

อ้างอิง

ข้อมูลเพิ่มเติม

PEAR::Auth package

PEAR  มีแพ็คเกจที่ชื่อว่า  Auth  ซึ่งช่วยอำนวยความสะดวกในการสร้างระบบตรวจสอบสิทธิ์ผู้ใช้ (authentication) โดยช่วยอำนวยความสะดวกตั้งแต่ การเพิ่มและลบผู้ใช้ การล็อกอิน การนำข้อมูลผู้ใช้มาแสดง การกำหนดระยะเวลาการล็อกอินและ Idle timeout และการตรวจสอบสิทธิ์ผู้ใช้งาน  ทำให้ช่วยลดเวลาในการพัฒนาโปรแกรมลงได้มาก 

สิ่งที่สำคัญคือ Auth รองรับระบบจัดเก็บข้อมูลของผู้ใช้หลากหลายประเภท ได้แก่

  • All databases supported by the PEAR database layer
  • All databases supported by the MDB database layer
  • All databases supported by the MDB2 database layer
  • Plaintext files
  • LDAP servers
  • POP3 servers
  • IMAP servers
  • vpopmail accounts (Using either PECL vpopmail or PEAR Net_Vpopmaild)
  • RADIUS
  • SAMBA password files
  • SOAP (Using either PEAR SOAP package or PHP5 SOAP extension)
  • PEAR website
  • Kerberos V servers
  • SAP servers

เรื่องของ PEAR

PEAR ย่อมาจาก PHP Extension and Application Repository เป็นที่เก็บรวบรวม component ของ PHP ที่ใช้กันบ่อยๆ และมีประโยชน์ ซึ่งผมได้นำมาลองใช้งานแล้วก็ช่วยให้เขียนโปรแกรมได้สะดวกและรวดเร็วขึ้นมากๆ เลย คิดว่าคงจะหยิบขึ้นมาเขียนสักวัน

บทความแนะนำเกี่ยวกับ PEAR

Getting Started with PEAR – PHP’s Low Hanging Fruit
PEAR Website
ฟังก์ชันที่ผมใช้งานอยู่ในตอนนี้

Date()
ใช้หาวันและเวลาปัจจุบันในรูปแบบต่างๆ
$date->getDate( $format_constant = DATE_FORMAT_ISO )
(รายละเอียดการใช้งาน http://www.modem-help.co.uk/help/diary20040326.html)

Text_Password()
ใช้สำหรับสร้าง password ขึ้นมาในรูปแบบต่างๆ
http://pear.php.net/manual/en/package.text.text-password.php

Custom Error Pages with PHP and Apache

Using PHP and Apache, you can turn your “Page Not Found” messages into more than bland error reports. You can serve an alternate page based on the name of the page that was not found, create a page on the fly from a database, or send an email about the missing page to a webmaster.

จะดีแค่ไหนถ้าเราสามารถเปลี่ยนข้อความ “Page Not Found” ที่ปรากฎเวลาคนเรียกดูไฟล์เว็บที่ไม่มีอยู่จริงให้เป็นอย่างอื่น?

PHP5 กับ MySQL bug?

หลังจากที่ผมได้ทำการติดตั้ง Apache 2.0.50 กับ PHP5 ไปแล้ว ทุกอย่างก็เหมือนจะทำงานได้ดีจนกระทั่ง ผมจะเพิ่ม extension ของ php_mysql.dll เพื่อให้ PHP สามารถติดต่อกับ MySQL ได้ ปรากฎว่าทำยังไงก็ไม่สามารถเพิ่ม mysql extension ได้ และจะเกิดข้อความ error แบบตัวอย่างข้างล่างนี้แหละ ซึ่งทำให้งง เพราะไฟล์มันก็อยู่ถูกที่แล้ว ลองกี่ทีๆ ก็เหมือนกัน

ข้อความเขียนไว้ว่า
PHP Startup: Unable to load dynamic library ‘d:program filesphpextphp_mysql.dll’ – The specified module could not be found.

เลยลองเข้าไปหาดูในเว็บ พบว่ามีคนโวยวายไว้ที่นี่เหมือนกัน http://bugs.php.net/bug.php?id=29224

ผมลองทำตามที่เขาเขียนไว้ แต่ก็ไม่ได้ผล ก็เลยลองใหม่ สิ่งที่ผมทำก็คือ
1. แก้ไข php.ini ให้เรียก module mysql ด้วยคำสั่ง
extension=php_mysql.dll

2. copy ไฟล์ libmysql.dll ไปไว้ที่ d:/windows/system32/

3. อย่าลืม restart Apache Web Server ใหม่

ปรากฎว่าคราวนี้ได้ผลแฮะ!

แล้วผมก็เจอคำตอบที่ FAQ ของ PHP ที่นี่ เจ้าตัว MySQL client libaries ไม่ได้ถูก bundle มากับ PHP5 นี่เอง นอกจากนี้ยังแนะนำให้ใช้ MySQLi แทนด้วย เพราะเนื่องจากว่าเจ้า MySQL extension ตัวที่มากับ PHP5 นั้นไม่ได้สนับสนุนฟังก์ชันต่างๆ ของ MySQL ในเวอร์ชันที่มากกว่า 4.1.0 ด้วย

งั้นผมลองเปลี่ยนมาใช้ MySQLi ดีกว่า วิธีการก็คือ
1. comment MySQL ซะ ด้วยการเติม ; ไปข้างหน้า
;extension=php_mysql.dll

2. เรียก module MySQLi ด้วยการเพิ่มคำสั่ง
extension=php_mysqli.dll

3. copy ไฟล์ libmysqli.dll ไปไว้ที่ d:/windows/system32/

4. อย่าลืม restart Apache Web Server ใหม่