แก้ปัญหาข้อความเตือนเวลาเรียก php cli

หากเกิดข้อความเตือนเมื่อเรียกคำสั่ง php แบบ cli (Command line) เช่น

$ /usr/bin/php --help
PHP Warning:  PHP Startup: memcache: Unable to initialize module
 Module compiled with module API=20050922, debug=0, thread-safety=0
 PHP    compiled with module API=20060613, debug=0, thread-safety=0
 These options need to match
 in Unknown on line 0
...

สามารถแก้ปัญหาโดยการใช้ option -n  ซึ่งหมายถึง php จะไม่ไปอ่านค่าต่างๆ ในไฟล์ php.ini   ตัวอย่างการใช้งานเช่น

$ /usr/bin/php --help -n

Object Relational Mapper (ORM)

Object-relational mapping (ORMO/RM, and O/R mapping) in computer software is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming languages.

From: http://en.wikipedia.org/wiki/Object-relational_mapping

หากมีเวลาก็ทดลองใช้งาน ORM ต่างๆ ได้

CodeIgniter – Session Bug within object storage

ผมใช้ CodeIginter แล้วเจอ error เกี่ยวกับ session library แบบนี้

A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: libraries/Session.php
Line Number: 715

ลองค้นดูในเน็ตแล้วพบว่าเป็นบั๊กของ session เกี่ยวกับ object storage วิธีการแก้ที่
http://codeigniter.com/forums/viewthread/95690/P0/

โดยให้แก้ไฟล์ system/libraries/Session.php ที่บรรทัด 683 และ  714  จาก

$data[$key] = str_replace('\', '{{slash}}', $val);

ให้่เป็น

if(!is_object($val))    $data[$key] = str_replace('{{slash}}', '\', $val);

Identifying iPhone browser

PHP:

  $iphone = strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone');
  $ipod = strpos($_SERVER['HTTP_USER_AGENT'], 'iPod');
  if($iphone || $ipod){
    header('Location: http://m.example.com/');
  }

JavaScript:

if((navigator.userAgent.indexOf('iPhone') != -1) || (navigator.userAgent.indexOf('iPod') != -1)){
  document.location = "http://m.example.com/";
}

ที่มา: http://eugen.io/2009/12/setting-up-your-web-site-to-run-on-iphone-browser/

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)

อ้างอิง

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

Permission denied: .htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable

If you are getting 403 error on your site with following messege in your error log

Permission denied: /home/user/public_html/subdomain/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable

Then it seems that the nobody user is not getting read and executing permission upto any of that folder.So make sure that the public_html and the subdomain are set read and executing permission.

If its not set then change it.

That will fix your issue.

Source: here

php.ini sections

เราสามารถเพิ่ม section ใน php.ini เพื่อให้กำหนดค่า config ที่ต้องการต่อโดเมน หรือต่อไดเรกทอรีได้ (เพิ่มใน PHP เวอร์ชัน 5.3.0 เป็นต้นไป)  ตัวอย่างเช่น

[HOST=dev.site.com]
error_reporting = E_ALL
display_errors = On
[PATH=/home/site/public/secure]
auto_prepend_file=security.php

PHP Error Handling

สำหรับ production servers ให้สร้างไฟล์ .htaccess และใส่ข้อมูลต่อไปนี้ (แก้ไขตามสมควร)

# PHP error handling for production servers
php_flag display_startup_errors false
php_flag display_errors false
php_flag html_errors false
php_flag log_errors true
php_flag ignore_repeated_errors false
php_flag ignore_repeated_source false
php_flag report_memleaks true
php_flag track_errors true
php_value docref_root 0
php_value docref_ext 0
php_value error_log /home/path/public_html/domain/PHP_errors.log
php_value error_reporting 999999999
log_errors_max_len 0

<Files /home/path/public_html/domain/PHP_errors.log>
 Order allow,deny
 Deny from all
 Satisfy All
</Files>

สำหรับ development servers ให้สร้างไฟล์ .htaccess และใส่ข้อมูลต่อไปนี้ (แก้ไขตามสมควร)

# PHP error handling for production servers
php_flag display_startup_errors true
php_flag display_errors true
php_flag html_errors true
php_flag log_errors true
php_flag ignore_repeated_errors false
php_flag ignore_repeated_source false
php_flag report_memleaks true
php_flag track_errors true
php_value docref_root 0
php_value docref_ext 0
php_value error_log /home/path/public_html/domain/PHP_errors.log
php_value error_reporting 999999999
php_value log_errors_max_len 0

<Files /home/path/public_html/domain/PHP_errors.log>
 Order allow,deny
 Deny from all
 Satisfy All
</Files>

ที่มา: http://perishablepress.com/press/2008/01/14/advanced-php-error-handling-via-htaccess/

ค้นหาค่า auto_increment ของ table ด้วย MDB2

        $sql = "SHOW TABLE STATUS LIKE 'table_name'";
        $res = $mdb2->query($sql);
        if (PEAR::isError($res)) {
            die($res->getMessage());
        }
        $result = $res->fetchRow();
        $next_id = $result['auto_increment'];