เล็กๆน้อยๆกับ UTF-8

Wednesday, November 5th, 2008

ก็บังเอิญมารื้อเว็บรถยนต์มือสองของตัวเองใหม่ แล้วทำให้เป็น UTF-8 ทั้งหมดจากเดิมใช้เป็น Tis-620 ผมว่าหลายๆเว็บอาจจะเคยมีปัญหากับเรื่องของการตัดคำด้วยการใช้ UTF-8 แน่นอน เพราะตอนที่ใช้พวก Tis-620 มันไม่มีปัญหาครับ แต่มันจะมีปัญหากับ UTF-8

ตัวอย่างการตัดคำที่ผิดพลาดครับ

utf-8-01.jpg

ลองดูที่มีตัวสี่เหลี่ยมนั่นแหล่ะครับที่เกิดจากการตัดคำบน UTF-8 แล้วมีปัญหา

ลองมาทดสอบกันง่ายๆกับโค๊ดนี้

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>
</head>
<body>
<?php
$text = “สวัสดีครับพ่อแม่พี่น้อง”;
$newtext = substr($text, 0,10);
echo $newtext ;
?>
</body>
</html>

เมื่อลองทดสอบกับไฟล์ตัวนี้จะได้ผลออกมาเป็น

สวั�

แบบนี้ก็ไม่ถูกต้องแน่นอน

แต่ก็สามารถแก้ไขได้ง่ายๆ ลองดูโค๊ดนี้เทียบกันครับ

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>
</head>
<body>
<?php
$text = “สวัสดีครับพ่อแม่พี่น้อง”;
$newtext = iconv_substr($text, 0,10, “UTF-8″);
echo $newtext ;
?>
</body>
</html>

ผลออกมาก็จะถูกต้องครับ ก็แสดงผล สวัสดีครับ ขึ้นมาครับ 

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

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>
</head>
<body>
<?php
$text = “สวัสดีครับพ่อแม่พี่น้อง”;
mb_internal_encoding(”utf8″);
$newtext = mb_substr($text, 0, 10);

echo $newtext ;
?>
</body>
</html>

ก็ไม่มีใครว่าเหมือนกันครับ ทั้ง 2 แบบก็ไม่ต่างกันครับ ก็เพียงแค่เรียกโมดูลการทำงานคนละตัวกัน

iconv_substr เป็นการใช้ library iconv ของ OS
ส่วนอีกอันหนึ่งนั้น เป็น built in function ของ php นั่นเอง (multibyte string)

ก็เลือกใช้กันไป…. ลองไปอ่านเพิ่มได้ที่ http://th.php.net/iconv_substr

Framework คือสิ่งที่ต้องการหรือไม่ ?

Wednesday, September 3rd, 2008

ที่หยิบเรื่อง PHP Framework มาพูดในครั้งนี้ไม่ใช่อะไร เพราะว่าตอนนี้งานที่ทำให้ฝรั่งเขาอยากได้มากๆคือ Zend Framework ซึ่งผมเองก็ไม่เคยจับมาก่อนเช่นกันสำหรับตัวนี้ เพราะเคยเล่นเจ้า CodeIgniter ตามที่ผมเคยลองที่ http://www.myblog.in.th/?p=305

คำถามของหลายๆคนตามมาว่า
ทำไมถึงใช้ Framework ?
แล้วทำไมผมถึงไม่ใช้ ทำเว็บตัวเอง ?

ทำไมถึงใช้ Framework ?
ส่วนตัวแล้วผมชอบในหลักการของ PHP Framework ที่มี MVC ซึ่งทันก็มีข้อดีก็คือ
- พัฒนาต่อง่าย
- เหมาะกับการทำงานเป็นทีม
- เหมาะกับ Application

ซึ่งเท่าที่ดูแล้ว Framework มันเหมาะกับการทำเป็น Application เฉพาะทางซะมากกว่าเช่น Web App ที่ทำหน้าที่เกี่ยวกับการเงิน , สารสนเทศ อะไรแนวนี้มากกว่าการทำเว็บไซต์ทั่วๆไป

แต่มันมีอยู่อย่างหนึ่งที่ผมไม่ชอบบนตัว PHP Framework ก็คือเรื่องของความเร็วในการประมวลผล มันคิดมากไป ขั้นตอนมากเกินไป ซึ่งเมื่อผมจับ Zend Framework เล่นดู ผมก็ต้องการที่จะรู้ว่ามันทำงานได้เร็วไหม แค่ไหน อย่างไร ก็ไม่แคร้วต้องทดสอบจับเวลามันครับ

ผมเชื่อมั่น 100% ว่าไม่มีทางที่ PHP Framework ใดจะประมวลผลได้เร็วเท่าเขียน PHP แบบปกติ หรือ เขียนในรูปแบบ OOP , Class , Function ครับ เพราะพิสูจน์มาแล้ว

ลองดูจากที่ผมเล่นตัว CodeIgniter โดยไม่ได้ติดต่อดาต้าเบสอะไรเลย แค่ดึง head body footer มาแสดงเท่านั้น แต่มันใช้เวลาคิดถึง 0.0383 วินาที ดังรูป

 

วกมาที่ทดสอบ Zend Framework กันบ้าง โดยผมทำตามตัวอย่างของการเริ่มต้นสร้างเว็บด้วย Zend Framework โดยติดต่อตาราง 1 ตาราง ข้อมูล 2 แถวเท่านั้น ได้ผลตามรูป

zend01.jpg 

โดยใช้ Process Time : 0.1391561031 วินาทีในการประมวลผล
ทีนี้ผมก็ทดสอบเขียน PHP ปกติโดยใช้งานติดต่อกับ Class ที่เขียนขึ้นเองในการเชื่อมต่อดาต้าเบส 1 ตาราง ข้อมูล 1000 แถว เรียกมาแสดงผลแล้วก็จับเวลา ซึ่งได้ผลแบบนี้

zend02.jpg 

เทียบกัน 2 อันเป็นไงบ้างครับ การเขียน PHP ปกตินั้นประมวลผลได้เร็วกว่าใช้ PHP Framework มากมายหลายขุมเลยทีเดียว

หากมาวิเคราะห์กันว่าหากเราใช้งาน Framework ในการทำเว็บไซต์ ผลกระทบที่ตามมาก็คืออะไรบ้าง
- ต้องการ Server ประสิทธิภาพสูงขึ้น
- ค่าใช้จ่ายสูงขึ้น
- ต้องการคนที่เข้าใจใน Framework นั้นๆในการพัฒนาต่อ
แล้วทำไมผมถึงไม่ใช้ ทำเว็บตัวเอง ?
ก็อย่างที่บอกไปครับ ผมเน้นงานด้าน OutPut มากกว่า Input เพราะผมต้องการนำเสนอเว็บ ไม่ได้ต้องการนำเสนอ Code เพราะหากผมสนใจแต่เรื่อง Code ที่ต้องเริศหรู ต้องเป็น Framework หรือเป็น OOP ทั้งหมด เว็บผมคงไม่สามารถใช้งานในระดับที่ CPU Load ต่ำขนาดนี้ได้

zend03.jpg 

ลองดูหน้าแรกของผมก็ได้ ติดต่อตารางทีละ 9 ตาราง (อาจจะมากกว่าเพราะมีส่วนของสคริป Banner ต่างๆที่รันผ่านการเรียกด้วย Javascript) แต่สามารถทำได้ที่ 0.0079 วินาที ซึ่งหากผมใช้งาน Framework ผมว่าไม่มีทางได้ต่ำกว่า 0.2 - 0.3 วินาทีอย่างแน่นอน ถึงแม้จะเอาเทคโนโลยี Cache ที่มีในตัว Framework มาใช้ก็ตาม

zend04.jpg 

และนี่คือเหตุผลที่ว่าทำไมผมถึงไม่ใช้ Framework ในเว็บของผมเอง แต่ผมเลือกใช้พวก OOP , Class ซะมากกว่า

อยู่ที่การคำนึงถึงการใช้งานของแต่ละระบบ แต่ละ Application ว่าต้องการอะไร ?
สำหรับผมแล้วผมคำนึงถึง “ผู้เสพ” มากกว่า “ผู้พัฒนา” ผู้เสพก็คือคนเข้าชมเว็บไซต์ หากเราทำให้เว็บของเรา
- เร็ว
- ข้อมูลถูกต้อง
- ระบบมีมาตรฐาน ปลอดภัย
เท่านี้มันก็มากพอแล้วครับ ส่วนผู้พัฒนา หากคุณเก่งซะอย่าง(ไม่ต้องมากก็ได้) ยังไงก็แก้ไขได้ครับ เพราะมันก็ใช้ OOP , Class  เท่านั้น ส่วน PHP Framework คุณไม่สามารถจ้าง PHP Programer ทั่วๆไปมาทำได้เลย ดังนั้นค่าจ้างก็ย่อมแพงขึ้นตามครับ

แต่ยังไงตอนนี้ก็ทำไปครับทำไงได้ ฝรั่งดันอยากได้ Zend Framework จากทำระบบ CMS ใช้เวลาสัก 2 วันเสร็จ ตอนนี้หากมาใช้ Framework 2 วันไม่มีทางเสร็จแน่นอน!!!

ลดกันเห็นๆกับ ob_gzhandler

Thursday, August 14th, 2008

วันนี้ผมได้มีโอกาสลองของกับเว็บตัวเองอีกแล้วกับการใช้ ob_gzhandler ในเว็บไซต์ Mocyc.com

ก็เนื่องมาจากผมเองชอบโมเว็บอยากให้เว็บไซต์ใช้ทรัพยากรในเครื่องให้น้อยที่สุด เครื่อง Server ทำงานได้สบายที่สุด ดังนั้นในเว็บ Mocyc.com จึงได้มีการใช้แนวคิดการออกแบบหลายๆอย่างเช่น

  • ลดและเลี่ยงการใช้ Join Table Database ให้น้อยที่สุด หรือ ไม่ใช้เลย
  • เขียนสคริป Cache เพื่อลดอัตราการติดต่อกับ MySQL ดาต้าเบส

ซึ่งก็ได้ผลดีและทำให้ Server ที่ใช้งานอยู่นั้นทำงานได้สบายๆ ไม่หนักมากมายนัก

และล่าสุด เมื่อราวๆ บ่าย 2 ของวันที่ 14 สค. 51 ผมเองก็ได้จูนเว็บ Mocyc.com อีกครั้ง โดยการใช้งาน ob_gzhandler หรือใช้ความสามารถของ gzip ครับ

php_gzip.jpg

ดูจากกราฟนะครับ เมื่อวานยังไม่ได้ใช้งาน ob_gzhandler ลองเทียบกับวันนี้หลัง 15.00 น. ดูครับ CPU LOAD ลดลงเป็นครึ่งเลยครับ ว๊าววววว…..

ob_gzhandler หมายความว่า ในกรณีที่ browser ของเราสามารถอ่านเวปที่มีการบีบอัดได้ ( header ที่ส่ง request ไปยัง server จะมีคำว่า enable gzip) พอเจ้า php (ที่มีการระบุใน script ว่า ob start , ob_gzhandler ) รู้ว่า browser ของเราสามารถรับเวปที่มีการบีบอัดได้ มันจะส่ง html ที่มีการบีบอัดมาแทน ดังนั้น แทนที่จะส่งมา 50,000-200,000 ไบต์ มันก็จะเหลือมาแค่ 5,000-10,000 ไบต์ แล้วมาคลายที่เครื่องเราแทน

ก่อนที่จะเอาลองเทสบนเว็บ Mocyc.com ผมได้ลองเทสใน localhost ในเครื่อง โดยการคิวรี่ข้อมูลมาแสดงผลจำนวน 1,000 ข้อมูล ในกรณีที่ไม่ได้ใช้ ob_gzhandler ใช้เวลาประมาณ 0.001 - 0.0012 sec แต่เมื่อผมใช้ ob_gzhandler จะใช้เวลาเฉลี่ยประมาณ 0.0009 - 0.001 sec. ซึ่งเทียบแล้วก็คือไวกว่าปกติครับ ก็เลยนำมาทดสอบใน Mocyc.com เลยครับ ซึ่งก็ได้ผลดังกราฟครับ

การใช้งานก็ไม่มีอะไรมากมายเลยครับ ก็แค่ใช้คำสั่ง

ob_start(’ob_gzhandler’);
ในกรณีที่ต้องการให้มีการบีบอัดข้อมูล

ob_start();
ในกรณีที่ไม่ต้องการบีบอัดข้อมูล

เดี๋ยวลองดูผลต่อไป แต่จากการทดสอบดูแล้วค่อนข้างน่าพอใจมากครับกับการเพิ่มคำสั่งเพิ่มไปแค่นิดเดียว

หากลองสังเกตุจะเห็นว่าช่วง 4 ทุ่มจะสูง เพราะเป็นช่วงที่คนเข้าเว็บเยอะครับ ส่วนตอนช่วงเที่ยงคืน นั่นคือ ผมสั่งให้ระบบผมทำงานอัตธนมัติในการลบประกาศซื้อขายที่หมดอายุ รวมไปถึงจัดการระบบดาต้าเบสต่างๆ โดยผมเขียนโปรแกรมสั่งให้มันทำงานช่วง 00.00 น. ครับ

สุดยอด 8 สคริป Shopping Cart

Tuesday, June 24th, 2008

ช่วงนี้ลูกค้าทำไมถามมาเยอะจริงๆ เรื่องอยากให้ทำเว็บ E-commerce ก็เลยไปหาข้อมูลเก่าๆที่เคย save ไว้ในเครื่องว่าสคริปไหนเด็ดๆบ้าง และก็ไปเยี่ยมดูสิว่าตอนนี้เขาพัฒนาไปถึงไหนแล้ว ก็เลยเอามาทำลิงก์ไว้ซะ เผื่อมีคนอยากได้สคริป

prestashop.jpg
ตัวนี้เจ๋งมากๆครับ คนไทยที่เคยใช้ OS Commerce มาเจอตัวนี้ผมว่าคนละขั้นกันเลยครับ ตัวนี้ใช้ Ajax เยอะมาก แต่ยอมรับว่าระบบเด็ดมากครับ
http://www.prestashop.com/

opencart.jpg
ตัวนี้มีดีที่มันใช้ง่าย และ ออกแบบมาเพื่อ SEO โดยเฉพาะ
http://www.opencart.com/

megenta.jpg
http://www.magentocommerce.com/

cubecart.jpg
ตัวนี้ก็ใช้งานได้ดีครับ เคยเอามาทำเว็บให้ลูกค้า ปรับแต่งง่ายดีครับ
http://www.cubecart.com/site/home/

agoracart.jpg
http://www.agoracart.com/

zencart.jpg
http://www.zen-cart.com/

oscommerce.jpg
ตัวนี้ผมว่าคงไม่มีใครที่ไม่รู้จัก เพราะมีคนเอาไปใช้แพร่หลายมากๆๆๆ ผมเองก็เคยใช้ และ เคยแปลเป็นไทยในเวอร์ชั่นแรกๆ มีคนเอาที่ผมแปลไปใช้เยอะเหมือนกัน แต่ตอนนี้มีภาษาไทยให้แล้วละ ดีจัง
http://www.oscommerce.com/

storesprite.jpg
http://www.storesprite.com/

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

จะหาค่า id ลำดับต่อไปทำยังไง ?

Wednesday, May 7th, 2008

เหอๆๆ ชื่อหัวข้อ งงๆ ป่าว ผมอ่านผมก็ยัง งงๆ เลยครับ แต่เอาเป็นว่าคุณๆที่เคยเขียนโปรแกรมที่ต้องมีการนำเอาค่า id ของตารางไปใช้งานต่อไป และค่า id ที่จะเอาไปนั้นเองในดาต้าเบสก็ดันเป็นข้อมูลแบบ ‘Auto_increment’ หรือ รันขึ้นไปเรื่อยๆอัตโนมัติอีกหล่ะทำไง

นี่ไงๆ เขียนแบบนี้เลย
$result = mysql_query(”SELECT MAX(order_id) AS now_id FROM orders “);
$row = mysql_fetch_assoc($result);
echo $row[’now_id’]+1;

หรือ
$result = mysql_query(”SELECT MAX(order_id)+1 AS next_id FROM orders “);
$row = mysql_fetch_assoc($result);
echo $row[’next_id’];

ก็ได้ค่าของ id ลำดับต่อไปแล้ว

ง่ายดีไหมครับ…….

แต่……มันไม่ใช่แค่นั้นนะสิ

สมมุติละกันว่า ตอนนี้ มีแถวอยู่แบบนี้ โดยที่ข้อมูลยังครบถ้วน id เป็นฟิลล์แบบ Auto_increment

+—-+————+————+
| id | txt | date |
+—-+————+————+
| 1 | wqwmo | 0211041039 |
| 2 | mote | 0210120016 |
| 3 | phpbuilder | 0211161642 |
| 4 | txt1 | 0211181109 |
| 5 | txt2 | 0211181109 |
+—-+————+————+

หากเราใช้คำสั่ง  mysql_query(”SELECT MAX(order_id) AS now_id FROM orders “);
ค่า now_id จะต้องเท่ากับ 5 ใช่หรือไม่ ?

ถูกต้องนะครับ…

แต่หากว่าเกิดเราลบ id ที่ 5 ไปหล่ะ มันก็จะเหลือข้อมูลแบบนี้
+—-+————+————+
| id | txt | date |
+—-+————+————+
| 1 | wqwmo | 0211041039 |
| 2 | mote | 0210120016 |
| 3 | phpbuilder | 0211161642 |
| 4 | txt1 | 0211181109 |
+—-+————+————+

และเมื่อเราใช้คำสั่ง mysql_query(”SELECT MAX(order_id) AS now_id FROM orders “);
ค่า now_id จะต้องเท่ากับ 4 ใช่หรือไม่ ?

ก็ถูกต้องนะครับ…

แต่จริงๆแล้ว id ที่จะถูกใช้งานเมื่อถูก insert ครั้งต่อไปมันคือ 6 ครับ

อ่าว เวร แล้วสิ งี้ทำไงดี

บางคนอาจจะใช้วิธี insert ข้อมูลเข้าไปก่อน แล้วค่อยใช้วิธี query ออกมาอีกครั้งหนึ่ง เพ่ือเอาค่า id ล่าสุดไปใช้งานต่อไป

สำหรับคนที่เคยทำแล้วอาจจะบอก ง่ายจริงๆ แต่หลายๆคนที่ไม่เคยใช้งาน ก็ลองเอาไปใช้งานนะ

$q = mysql_query(”show table status from DATABASE_NAME like ‘TABLE_NAME’ “) or die(mysql_error());
echo mysql_result($q, 0, ‘Auto_increment’);

รับรองคราวนี้ได้ค่า id ต่อไปของข้อมูลแบบ Auto_increment ที่ถูกต้องและแน่นอน

วิธีนี้เหมาะกับการต้อวงการทราบค่า id ต่อไป เหมือนที่แสดงใน phpmyadmin ที่บอกว่า
ต่อไป Autoindex        4
ประมาณนี้ครับ

Editor's Talk!

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

นายแม็ค

ค้นหา :