<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jQuery, Ajax, PHP, JSON, XML, Web Technologies &#187; PHP</title>
	<atom:link href="http://blog.chonla.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.chonla.com</link>
	<description>คุยกันเรื่อง jQuery, Ajax, PHP, JSON, XML และ Web Technologies เป็นภาษาไทยกันดีกว่า</description>
	<lastBuildDate>Tue, 17 Jan 2012 18:27:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>วันแรกของเดือน วันสุดท้ายของเดือน เป็นวันอะไรนะ</title>
		<link>http://blog.chonla.com/2012/01/%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b9%81%e0%b8%a3%e0%b8%81%e0%b8%82%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%94%e0%b8%b7%e0%b8%ad%e0%b8%99-%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b8%aa%e0%b8%b8%e0%b8%94%e0%b8%97%e0%b9%89/</link>
		<comments>http://blog.chonla.com/2012/01/%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b9%81%e0%b8%a3%e0%b8%81%e0%b8%82%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%94%e0%b8%b7%e0%b8%ad%e0%b8%99-%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b8%aa%e0%b8%b8%e0%b8%94%e0%b8%97%e0%b9%89/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 18:22:22 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[Date]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=350</guid>
		<description><![CDATA[วิธีหาว่าวันแรกของเดือนเป็นวันอะไร หรือวันสุดท้ายของเดือนเป็นวันอะไร ง่ายมาก วิธีตรงไปตรงมา เราประยุกต์ใช้ฟังก์ชั่น 2 ฟังก์ชั่นคือ strtotime() กับ date() ผลที่ได้จะออกมาแบบนี้ function firstDayOfMonth($monthstamp) { // $monthstamp มีหน้าตาเป็น mmyyyy ครับ // เช่น เราต้องการทราบว่าเดือนมกราคม ปี 2012 เป็นวันอะไร ก็ใช้ firstDayOfMonth('012012') // ปีที่ใช้ก็ใช้เป็นปี ค.ศ. นะครับ     $mm = substr($monthstamp,0,2); $yyyy = substr($monthstamp,-4); return date('w',strtotime("{$mm}/01/{$yyyy} 00:00:00")); } ส่วนวิธีหาวันสุดท้ายของเดือนก็ทำแบบเดียวกันครับ ซับซ้อนขึ้นอีกแค่นิดเดียวเอง function lastDayOfMonth($monthstamp) {     $mm = substr($monthstamp,0,2); $yyyy = substr($monthstamp,-4); return [...]]]></description>
			<content:encoded><![CDATA[<p>วิธีหาว่าวันแรกของเดือนเป็นวันอะไร หรือวันสุดท้ายของเดือนเป็นวันอะไร ง่ายมาก วิธีตรงไปตรงมา เราประยุกต์ใช้ฟังก์ชั่น 2 ฟังก์ชั่นคือ strtotime() กับ date() ผลที่ได้จะออกมาแบบนี้</p>
<p><span id="more-350"></span></p>
<pre name="code" class="js">function firstDayOfMonth($monthstamp) {
    // $monthstamp มีหน้าตาเป็น mmyyyy ครับ
    // เช่น เราต้องการทราบว่าเดือนมกราคม ปี 2012 เป็นวันอะไร ก็ใช้ firstDayOfMonth('012012')
    // ปีที่ใช้ก็ใช้เป็นปี ค.ศ. นะครับ
    $mm = substr($monthstamp,0,2);
    $yyyy = substr($monthstamp,-4);
    return date('w',strtotime("{$mm}/01/{$yyyy} 00:00:00"));
}</pre>
<p>ส่วนวิธีหาวันสุดท้ายของเดือนก็ทำแบบเดียวกันครับ ซับซ้อนขึ้นอีกแค่นิดเดียวเอง</p>
<pre name="code" class="js">function lastDayOfMonth($monthstamp) {
    $mm = substr($monthstamp,0,2);
    $yyyy = substr($monthstamp,-4);
    return date('w',strtotime('-1 second', strtotime('+1 month', strtotime("{$mm}/01/{$yyyy} 00:00:00"))));
}</pre>
<p>ค่าที่ได้จะมีค่าตั้งแต่ 0 ถึง 6 มีความหมายตั้งแต่วันอาทิตย์ (0) ถึงเสาร์ (6) ครับ</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2012%2F01%2F%25e0%25b8%25a7%25e0%25b8%25b1%25e0%25b8%2599%25e0%25b9%2581%25e0%25b8%25a3%25e0%25b8%2581%25e0%25b8%2582%25e0%25b8%25ad%25e0%25b8%2587%25e0%25b9%2580%25e0%25b8%2594%25e0%25b8%25b7%25e0%25b8%25ad%25e0%25b8%2599-%25e0%25b8%25a7%25e0%25b8%25b1%25e0%25b8%2599%25e0%25b8%25aa%25e0%25b8%25b8%25e0%25b8%2594%25e0%25b8%2597%25e0%25b9%2589%2F&amp;title=%E0%B8%A7%E0%B8%B1%E0%B8%99%E0%B9%81%E0%B8%A3%E0%B8%81%E0%B8%82%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%94%E0%B8%B7%E0%B8%AD%E0%B8%99%20%E0%B8%A7%E0%B8%B1%E0%B8%99%E0%B8%AA%E0%B8%B8%E0%B8%94%E0%B8%97%E0%B9%89%E0%B8%B2%E0%B8%A2%E0%B8%82%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%94%E0%B8%B7%E0%B8%AD%E0%B8%99%20%E0%B9%80%E0%B8%9B%E0%B9%87%E0%B8%99%E0%B8%A7%E0%B8%B1%E0%B8%99%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3%E0%B8%99%E0%B8%B0" id="wpa2a_2"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2012/01/%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b9%81%e0%b8%a3%e0%b8%81%e0%b8%82%e0%b8%ad%e0%b8%87%e0%b9%80%e0%b8%94%e0%b8%b7%e0%b8%ad%e0%b8%99-%e0%b8%a7%e0%b8%b1%e0%b8%99%e0%b8%aa%e0%b8%b8%e0%b8%94%e0%b8%97%e0%b9%89/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Magic Methods เรียกใช้พี่สิจ๊ะ แล้วน้องจะสบาย</title>
		<link>http://blog.chonla.com/2011/11/magic-methods-%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%9e%e0%b8%b5%e0%b9%88%e0%b8%aa%e0%b8%b4%e0%b8%88%e0%b9%8a%e0%b8%b0-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7/</link>
		<comments>http://blog.chonla.com/2011/11/magic-methods-%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%9e%e0%b8%b5%e0%b9%88%e0%b8%aa%e0%b8%b4%e0%b8%88%e0%b9%8a%e0%b8%b0-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 10:38:54 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Object Oriented]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Magic Methods]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=339</guid>
		<description><![CDATA[Magic methods คืออะไร ทำไมผมถึงเกริ่นหัวว่ามันจำอำนวยความสะดวกสบายขนาดนั้น Magic method เป็น method ใน class ทั่วไปที่จะถูกเรียกก็ต่อเมื่อเกิดเงื่อนไขอย่างใดอย่างหนึ่งที่ตรงกับ method นั้น ๆ ในความเป็นจริงแล้ว magic methods นั้น ไม่ได้มีอะไรวิเศษไปกว่า method ธรรมดาเลย เรียกให้ง่ายก็คือจริง ๆ แล้ว ตัว magic method ก็คือ method ธรรมดานี่แหละ เพียงแค่ว่า มันไม่ได้ถูกเรียกตรง ๆ เหมือนกับการเรียกใช้งาน method อื่น ๆ แต่อย่างที่บอกตอนต้น คือเมื่อเกิดเหตุการณ์ที่มีเงื่อนไขตรงแล้ว method นี้จะถูกเรียกโดยอัตโนมัติ ตัว magic methods เองจะขึ้นต้นด้วยตัว underscore สองตัวติดกัน ( __ ) ดังนั้นเราควรหลีกเลี่ยงการตั้งชื่อ method ที่ขึ้นต้นด้วย __ นะครับ [...]]]></description>
			<content:encoded><![CDATA[<p>Magic methods คืออะไร ทำไมผมถึงเกริ่นหัวว่ามันจำอำนวยความสะดวกสบายขนาดนั้น</p>
<p>Magic method เป็น method ใน class ทั่วไปที่จะถูกเรียกก็ต่อเมื่อเกิดเงื่อนไขอย่างใดอย่างหนึ่งที่ตรงกับ method นั้น ๆ ในความเป็นจริงแล้ว magic methods นั้น ไม่ได้มีอะไรวิเศษไปกว่า method ธรรมดาเลย เรียกให้ง่ายก็คือจริง ๆ แล้ว ตัว magic method ก็คือ method ธรรมดานี่แหละ เพียงแค่ว่า มันไม่ได้ถูกเรียกตรง ๆ เหมือนกับการเรียกใช้งาน method อื่น ๆ แต่อย่างที่บอกตอนต้น คือเมื่อเกิดเหตุการณ์ที่มีเงื่อนไขตรงแล้ว method นี้จะถูกเรียกโดยอัตโนมัติ</p>
<p><span id="more-339"></span>ตัว magic methods เองจะขึ้นต้นด้วยตัว underscore สองตัวติดกัน ( __ ) ดังนั้นเราควรหลีกเลี่ยงการตั้งชื่อ method ที่ขึ้นต้นด้วย __ นะครับ</p>
<p>เรามารู้จัก magic methods ที่ php เตรียมไว้ให้เรากัน</p>
<p><strong><span style="color: #0000ff;">__sleep()</span></strong> และ <strong><span style="color: #0000ff;">__wakeup()</span></strong></p>
<p>จะถูกเรียกเมื่อมีการเรียกใช้งานคำสั่ง serialize() และ unserialize() โดยเมื่อเราเรียก serialize() กับ object ของ class ที่มี method __sleep() มันจะทำการเรียกใช้งาน method __sleep() ก่อนที่จะทำการ serialize object ของเรา และจะเอาค่าที่ return จาก __sleep() ไป serialize() (ถ้าไม่มีการคืนค่าอะไรกลับไป คำสั่ง serialize จะทำการ serialize ค่า NULL)</p>
<p>ในทำนองเดียวกัน คำสั่ง unserialize() จะไปเรียกคำสั่ง __wakeup() ก่อนที่จะทำการ unserialize(); นั่นเอง</p>
<p><span style="color: #0000ff;"><strong>__tostring()</strong></span></p>
<p>ชื่อ method ค่อนข้างชัดเจน method นี้เอาไว้ใช้สำหรับการประมวลผล object แบบ string เช่น เรามี object ตัวหนึ่ง คือ $obj เราสามารถใช้คำสั่ง echo $obj ได้เลย โดยที่มันจะไปเรียก magic method __tostring อัตโนมัติ ค่าที่ส่งกลับจาก method นี้จะถูกส่งต่อให้ echo อีกทีหนึ่งนั่นเอง</p>
<p><span style="color: #0000ff;"><strong>__invoke()</strong></span></p>
<p>magic method __invoke() นี้จะถูกเรียกเมื่อมีการเรียกใช้งาน object ของเราเป็น function เช่น เรามี object ชื่อ $obj เราสามารถเรียกใช้เป็น $obj(&#8216;test&#8217;) ได้เลย โดยที่ค่า &#8216;test&#8217; จะถูกส่งผ่านไปให้ __invoke() นั่นเอง</p>
<p><span style="color: #0000ff;"><strong>__set_state()</strong></span></p>
<p>เป็น method ที่ถูกเรียกเมื่อมีการเรียกใช้งานคำสั่ง var_export กับ object ของ class ค่าที่ถูกส่งคืนกลับมาจะถูกส่งไปให้ var_export อีกทีหนึ่ง</p>
<p><span style="color: #0000ff;"><strong>__construct()</strong></span></p>
<p>สำหรับคนที่เขียน object oriented น่าจะรู้จัก method นี้ดี method นี้จะถูกเรียกเมื่อ class ของเราถูก instantiate เป็น object ครับ</p>
<p><span style="color: #0000ff;"><strong>__destruct()</strong></span></p>
<p>จะถูกเรียกเมื่อ object ของเราถูกทำลาย (ทำลายแบบทั้ง implicit คือ ถูกทำลายไปเอง ไม่ได้สั่งทำลาย เช่น ออกจาก variable scope และทำลายแบบ explicit คือ ทำลายด้วยคำสั่ง unset)</p>
<p><span style="color: #0000ff;"><strong>__call()</strong></span></p>
<p>จะถูกเรียกเมื่อมีการเรียกใช้ method ที่ใช้งานไม่ได้ (ไม่มี method นั้นใน class หรือ method นั้นเข้าถึงไม่ได้ เช่น private method)</p>
<p><strong><span style="color: #0000ff;">__callStatic()</span></strong></p>
<p>เหมือน __call() เพียงแค่ใช้กับ static method ครับ</p>
<p><span style="color: #0000ff;"><strong>__get()</strong></span></p>
<p>ถูกเรียกเมื่อมีการอ้างถึง property ที่เข้าถึงไม่ได้ของ class (ไม่มี property นั้น หรือเข้าถึงไม่ได้จากสาเหตุอื่น เช่น private property)</p>
<p><span style="color: #0000ff;"><strong>__set()</strong></span></p>
<p>ถูกเรียกเมื่อมีการกำหนดค่าให้กับ property ที่เข้าถึงไม่ได้ของ class</p>
<p><span style="color: #0000ff;"><strong>__isset()</strong></span></p>
<p>ถูกเรียกเมื่อมีการเช็คค่า property ที่เข้าถึงไม่ได้ ของ class ว่าถูกกำหนดค่าไว้หรือไม่ผ่านคำสั่ง isset()</p>
<p><span style="color: #0000ff;"><strong>__unset()</strong></span></p>
<p>ถูกเรียกเมื่อมีการทำลาย property ที่เข้าถึงไม่ได้ ของ class ผ่านคำสั่ง unset()</p>
<p><span style="color: #0000ff;"><strong>__clone()</strong></span></p>
<p>ถูกเรียกเมื่อมีการสั่ง clone object ผ่าน คำสั่ง clone</p>
<p>ตัวอย่างการนำ magic methods มาประยุกต์ใช้คือการทำ data binding แบบง่าย ๆ ครับ</p>
<pre class="js">&lt;?php
class DataBind {
	public $buffer;

	public function __construct() {
		$buffer = array();
	}

	public function __call($fn, $args) {
		if (preg_match('/^Get([A-Z][a-zA-Z0-9]*)$/', $fn, $m)) {
			return $this-&gt;buffer[$m[1]];
		} elseif (preg_match('/^Set([A-Z][a-zA-Z0-9]*)$/', $fn, $m)) {
			$this-&gt;buffer[$m[1]] = $args[0];
		} else {
			echo 'No method found: ' . $fn . "\n";
		}
	}
}

$data = new DataBind();
$data-&gt;SetBook('Harry Potter');
$data-&gt;SetName('John Doe');
$data-&gt;NoMethod();
echo "My name is " . $data-&gt;GetName() . ".\n";
echo "I love a book titled " . $data-&gt;GetBook() . ".\n";
?&gt;</pre>
<p>จะได้ output เป็น</p>
<pre class="js">No method found: NoMethod
My name is John Doe.
I love a book titled Harry Potter.</pre>
<pre class="js">ลองเอาไปประยุกต์ใช้กันดูนะครับ <img src='http://blog.chonla.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </pre>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2011%2F11%2Fmagic-methods-%25e0%25b9%2580%25e0%25b8%25a3%25e0%25b8%25b5%25e0%25b8%25a2%25e0%25b8%2581%25e0%25b9%2583%25e0%25b8%258a%25e0%25b9%2589%25e0%25b8%259e%25e0%25b8%25b5%25e0%25b9%2588%25e0%25b8%25aa%25e0%25b8%25b4%25e0%25b8%2588%25e0%25b9%258a%25e0%25b8%25b0-%25e0%25b9%2581%25e0%25b8%25a5%25e0%25b9%2589%25e0%25b8%25a7%2F&amp;title=Magic%20Methods%20%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%81%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%9E%E0%B8%B5%E0%B9%88%E0%B8%AA%E0%B8%B4%E0%B8%88%E0%B9%8A%E0%B8%B0%20%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B8%99%E0%B9%89%E0%B8%AD%E0%B8%87%E0%B8%88%E0%B8%B0%E0%B8%AA%E0%B8%9A%E0%B8%B2%E0%B8%A2" id="wpa2a_4"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2011/11/magic-methods-%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%9e%e0%b8%b5%e0%b9%88%e0%b8%aa%e0%b8%b4%e0%b8%88%e0%b9%8a%e0%b8%b0-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>เวลาตอนนี้อยู่ในช่วงเวลานั้นหรือเปล่านะ&#8230;</title>
		<link>http://blog.chonla.com/2011/03/%e0%b9%80%e0%b8%a7%e0%b8%a5%e0%b8%b2%e0%b8%95%e0%b8%ad%e0%b8%99%e0%b8%99%e0%b8%b5%e0%b9%89%e0%b8%ad%e0%b8%a2%e0%b8%b9%e0%b9%88%e0%b9%83%e0%b8%99%e0%b8%8a%e0%b9%88%e0%b8%a7%e0%b8%87%e0%b9%80%e0%b8%a7/</link>
		<comments>http://blog.chonla.com/2011/03/%e0%b9%80%e0%b8%a7%e0%b8%a5%e0%b8%b2%e0%b8%95%e0%b8%ad%e0%b8%99%e0%b8%99%e0%b8%b5%e0%b9%89%e0%b8%ad%e0%b8%a2%e0%b8%b9%e0%b9%88%e0%b9%83%e0%b8%99%e0%b8%8a%e0%b9%88%e0%b8%a7%e0%b8%87%e0%b9%80%e0%b8%a7/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 11:05:43 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Time]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=314</guid>
		<description><![CDATA[ตอนนี้เป็นเวลา 17.40 แล้ว (ตอนที่เขียน) &#8230; เอ&#8230; เวลาตอนนี้อยู่ในช่วงเวลา 13.00 &#8211; 21.00 หรือเปล่านะ ก็ต้องใช่น่ะสิ เพราะว่า 13.00 &#60;= 17.40 &#60;= 21.00 นี่นา ใคร ๆ ก็รู้ ผมไม่ได้อัพเดทบล็อกมาหลายเดือนเลยครับ ด้วยเหตุผลหลาย ๆ อย่างทำให้ผมมีเวลาไม่ค่อยมากเหมือนเก่า และที่สำคัญ หลาย ๆ ครั้งผมคิดไม่ออกว่าจะเขียนอะไรดีครับ entry นี้ เป็นไอเดียที่ผมไปได้มาตอนที่ไปประชุมวิชาการที่ญี่ปุ่นครับ ลองอ่านแล้วลองไปปรับใช้กันดูนะครับ เวลาตอนนี้ อยู่ในช่วงเวลานั้นหรือเปล่า เป็นแนวความคิดง่าย ๆ ที่ใช้สำหรับเช็คว่า เวลาใด ๆ นั้น อยู่ในช่วงเวลาที่เรากำหนดหรือเปล่า ตามที่ยกตัวอย่างไปตอนต้น วิธีการเช็คแบบไม่ต้องคิดอะไรมากก็ทำง่าย ๆ ผมจะอธิบายแบบค่อย ๆ เป็นค่อย ๆ ไปทีละขั้นนะครับ $t = (int)date("G", time()); [...]]]></description>
			<content:encoded><![CDATA[<p>ตอนนี้เป็นเวลา 17.40 แล้ว (ตอนที่เขียน) &#8230; เอ&#8230; เวลาตอนนี้อยู่ในช่วงเวลา 13.00 &#8211; 21.00 หรือเปล่านะ ก็ต้องใช่น่ะสิ เพราะว่า 13.00 &lt;= 17.40 &lt;= 21.00 นี่นา ใคร ๆ ก็รู้</p>
<p>ผมไม่ได้อัพเดทบล็อกมาหลายเดือนเลยครับ ด้วยเหตุผลหลาย ๆ อย่างทำให้ผมมีเวลาไม่ค่อยมากเหมือนเก่า และที่สำคัญ หลาย ๆ ครั้งผมคิดไม่ออกว่าจะเขียนอะไรดีครับ</p>
<p>entry นี้ เป็นไอเดียที่ผมไปได้มาตอนที่ไปประชุมวิชาการที่ญี่ปุ่นครับ ลองอ่านแล้วลองไปปรับใช้กันดูนะครับ</p>
<p><span id="more-314"></span>เวลาตอนนี้ อยู่ในช่วงเวลานั้นหรือเปล่า เป็นแนวความคิดง่าย ๆ ที่ใช้สำหรับเช็คว่า เวลาใด ๆ นั้น อยู่ในช่วงเวลาที่เรากำหนดหรือเปล่า ตามที่ยกตัวอย่างไปตอนต้น วิธีการเช็คแบบไม่ต้องคิดอะไรมากก็ทำง่าย ๆ ผมจะอธิบายแบบค่อย ๆ เป็นค่อย ๆ ไปทีละขั้นนะครับ</p>
<pre>$t = (int)date("G", time());</pre>
<p>ค่า $t ที่ได้ ก็จะเป็นเวลาชั่วโมง มีค่าตั้งแต่ 0-23 ครับ มี type เป็น int (จากการ casting ด้วย int) ด้านหน้าแหละครับ</p>
<p>สมมติว่าช่วงที่เรากำหนดไว้มี 2 ช่วงคือ ช่วง A คือ 10-21 (10 โมงเช้า ถึง 3 ทุ่ม) และ ช่วง B คือ 21-10 (3 ทุ่ม ถึง 10 โมงเช้า) สมมติให้แต่ละช่วงเป็น array ที่มี 2 element โดย element ที่ 0 คือเวลาเริ่มต้น และ element ที่ 1 คือเวลาสิ้นสุด ดังนั้น</p>
<pre>$A = array(10, 21);
$B = array(21, 10);</pre>
<p>ดังนั้นสำหรับ $A แล้ว การเช็คก็จะง่าย ๆ ใช่มั๊ยครับ แค่ใช้ว่า <span style="color: #0000ff;">if (($A[0] &lt;= $t) &amp;&amp; ($t &lt;= $A[1]))</span> เท่านั้นเอง ในขณะที่ $B จะไม่สามารถทำแบบนี้ได้ เพราะเวลาของ element ที่ 1 มีค่าน้อยกว่า element ที่ 0 ดังนั้นทำให้เราต้องเช็คอีกแบบหนึ่งแทน โดยสามารถทำได้ 2 แบบครับ คือ <span style="color: #0000ff;">if ((($B[0] &lt;= $t) &amp;&amp; ($t &lt;= 23)) || (($t &lt;= 0) &amp;&amp; ($t &lt;= $B[1])))</span> คือ แบ่งช่วงก่อนเที่ยงคืนและหลังเที่ยงคืนมาเช็คนั่นเองครับ หรืออีกวิธีคือ <span style="color: #0000ff;">if (!(($B[1] &lt; $t) &amp;&amp; ($t &lt; $B[0])))</span> ครับ นั่นคือเช็คว่าไม่อยู่ในช่วงนอกช่วงเวลาที่กำหนดนั่นเองครับ</p>
<p>จะเห็นได้ว่า การทำแบบนี้จะต้องมาเช็คช่วงว่าตัวแรกน้อยกว่าหรือมากกว่าตัวหลัง แล้วแยกไปเช็คตามวิธีที่สอดคล้องกัน</p>
<p>ทีนี้มาลองดูวิธีที่ผมคิดว่าน่าจะง่ายกว่ากันมั่ง</p>
<p>วิธีนี้ มีข้อกำหนดให้ช่วงเวลาเริ่มต้นจะต้องน้อยกว่าช่วงเวลาสิ้นสุดเสมอ โดยให้เวลาที่เลยเที่ยงคืนไป จะให้นับต่อไปเรื่อย ๆ จาก 23 ครับ ไม่ต้องวนกลับไปนับ 0 ใหม่ ดังนั้น ช่วงของ $A และ $B ใหม่ จะได้เป็น</p>
<pre>$A = array(10, 21);
$B = array(21, 34); // 34 คือ 24 + 10 นั่นเอง เอา 10 โมงเช้า + เวลาหลังเที่ยงคืน</pre>
<p>วิธีการเช็คก็ง่ายนิดเดียวครับ โดยการใช้แบบนี้ครับ <span style="color: #0000ff;">if ((($A[0] &lt;= $t) &amp;&amp; ($t &lt;= $A[1])) || (($A[0] &lt;= ($t+24)) &amp;&amp; (($t+24) &lt;= $A[1])))</span> วิธีแบบนี้ใช้ได้กับทั้ง $A และ $B ครับ นั่นคือเอาเวลาปัจจุบันมาดูว่าอยู่ในช่วงเวลาปกติหรือเปล่า หรือว่าอยู่ในช่วงเวลาข้ามวันไปแล้ว (โดยการ +24 แล้วเอาไปเช็ค)</p>
<p>วิธีนี้ผมได้แนวความคิดมาหลังจากที่ผมเห็นป้ายหน้าตึก ropongi hill ที่ระบุเวลาเปิดปิดไว้ว่า ปิดเวลา 25:00 ครับ (ตี 1) ผมเลยเอามาคิดว่าทำไมถึงต้อง 25:00 ทำไมไม่เป็น 1:00 แล้วจะเอาไปใช้งานง่าย ๆ ได้ยังไง ที่เหลือผมก็คิดเองเออเองมาเป็นแบบที่เขียนให้อ่านกันนี่แหละครับ ใครมีวิธีที่น่าสนใจกว่า เอามาแชร์กันได้นะครับ</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2011%2F03%2F%25e0%25b9%2580%25e0%25b8%25a7%25e0%25b8%25a5%25e0%25b8%25b2%25e0%25b8%2595%25e0%25b8%25ad%25e0%25b8%2599%25e0%25b8%2599%25e0%25b8%25b5%25e0%25b9%2589%25e0%25b8%25ad%25e0%25b8%25a2%25e0%25b8%25b9%25e0%25b9%2588%25e0%25b9%2583%25e0%25b8%2599%25e0%25b8%258a%25e0%25b9%2588%25e0%25b8%25a7%25e0%25b8%2587%25e0%25b9%2580%25e0%25b8%25a7%2F&amp;title=%E0%B9%80%E0%B8%A7%E0%B8%A5%E0%B8%B2%E0%B8%95%E0%B8%AD%E0%B8%99%E0%B8%99%E0%B8%B5%E0%B9%89%E0%B8%AD%E0%B8%A2%E0%B8%B9%E0%B9%88%E0%B9%83%E0%B8%99%E0%B8%8A%E0%B9%88%E0%B8%A7%E0%B8%87%E0%B9%80%E0%B8%A7%E0%B8%A5%E0%B8%B2%E0%B8%99%E0%B8%B1%E0%B9%89%E0%B8%99%E0%B8%AB%E0%B8%A3%E0%B8%B7%E0%B8%AD%E0%B9%80%E0%B8%9B%E0%B8%A5%E0%B9%88%E0%B8%B2%E0%B8%99%E0%B8%B0%26%238230%3B" id="wpa2a_6"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2011/03/%e0%b9%80%e0%b8%a7%e0%b8%a5%e0%b8%b2%e0%b8%95%e0%b8%ad%e0%b8%99%e0%b8%99%e0%b8%b5%e0%b9%89%e0%b8%ad%e0%b8%a2%e0%b8%b9%e0%b9%88%e0%b9%83%e0%b8%99%e0%b8%8a%e0%b9%88%e0%b8%a7%e0%b8%87%e0%b9%80%e0%b8%a7/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>เลิกใช้เหอะไอ้ .inc น่ะ</title>
		<link>http://blog.chonla.com/2010/09/%e0%b9%80%e0%b8%a5%e0%b8%b4%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%80%e0%b8%ab%e0%b8%ad%e0%b8%b0%e0%b9%84%e0%b8%ad%e0%b9%89-inc-%e0%b8%99%e0%b9%88%e0%b8%b0/</link>
		<comments>http://blog.chonla.com/2010/09/%e0%b9%80%e0%b8%a5%e0%b8%b4%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%80%e0%b8%ab%e0%b8%ad%e0%b8%b0%e0%b9%84%e0%b8%ad%e0%b9%89-inc-%e0%b8%99%e0%b9%88%e0%b8%b0/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 18:43:00 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[Extension]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=293</guid>
		<description><![CDATA[เคยเขียนเว็บที่เป็น แล้วมีหน้าที่ต้อง include เข้ามาใช่มั๊ยครับ หน้า include ที่ว่านี้ ผมไม่ได้หมายถึงแค่ส่วนประกอบบนหน้าเว็บอย่างเดียวนะครับ แต่ผมรวมถึงพวกค่า config, ค่า constant, function ต่าง ๆ ที่ทำเป็น library ไว้ ฯลฯ ตั้งชื่อนามสกุลไฟล์พวกนั้นไว้ว่าอะไรครับ .inc หรือเปล่า เลิกใช้เถอะครับ ใส่นามสกุลอย่างที่มันควรจะเป็นเถอะครับ ผมเคยเห็นคนใช้ไฟล์นามสกุล .inc ครั้งแรกตอนสมัยเขียน ASP สมัยนั้นผมยังเป็นเด็กเอ๊าะ ๆ วัยละอ่อนที่ไม่รู้ประสีประสาอะไร มันจะมีไฟล์ที่ผมใช้ประจำอยู่ไฟล์นึงที่ผมโหลดมาจากในเน็ต มันมีชื่อเต็ม ๆ ว่า adodb.inc ครับ ไฟล์นี้เป็น text file ธรรมดานี่แหละ ข้างในเป็น ASP Script (Server-Sided VBScript) ที่มีการประกาศค่าคงที่ต่าง ๆ มากมาย ที่ช่วยให้ชีวิตในการเขียน ASP สะดวกขึ้นอย่างมาก ผมใช้มันมาตลอดเวลาที่ผมเขียน ASP จนกระทั่งผมเลิกเขียน [...]]]></description>
			<content:encoded><![CDATA[<p>เคยเขียนเว็บที่เป็น แล้วมีหน้าที่ต้อง include เข้ามาใช่มั๊ยครับ หน้า include ที่ว่านี้ ผมไม่ได้หมายถึงแค่ส่วนประกอบบนหน้าเว็บอย่างเดียวนะครับ แต่ผมรวมถึงพวกค่า config, ค่า constant, function ต่าง ๆ ที่ทำเป็น library ไว้ ฯลฯ ตั้งชื่อนามสกุลไฟล์พวกนั้นไว้ว่าอะไรครับ .inc หรือเปล่า เลิกใช้เถอะครับ ใส่นามสกุลอย่างที่มันควรจะเป็นเถอะครับ</p>
<p><span id="more-293"></span>ผมเคยเห็นคนใช้ไฟล์นามสกุล .inc ครั้งแรกตอนสมัยเขียน ASP สมัยนั้นผมยังเป็นเด็กเอ๊าะ ๆ วัยละอ่อนที่ไม่รู้ประสีประสาอะไร มันจะมีไฟล์ที่ผมใช้ประจำอยู่ไฟล์นึงที่ผมโหลดมาจากในเน็ต มันมีชื่อเต็ม ๆ ว่า adodb.inc ครับ ไฟล์นี้เป็น text file ธรรมดานี่แหละ ข้างในเป็น ASP Script (Server-Sided VBScript) ที่มีการประกาศค่าคงที่ต่าง ๆ มากมาย ที่ช่วยให้ชีวิตในการเขียน ASP สะดวกขึ้นอย่างมาก ผมใช้มันมาตลอดเวลาที่ผมเขียน ASP จนกระทั่งผมเลิกเขียน ASP ไป</p>
<p>จริง ๆ ผมไม่ได้หมายถึงแค่ .inc อย่างเดียวหรอกครับ ผมหมายถึง text file ทุกชนิดที่ server มันไม่รู้จัก หรือประมวลผลไม่ได้ ไม่ว่าจะเป็น .txt, .conf, .config, .inc, .duck, .dat, .ini หรือแม้กระทั่งไม่ใส่นามสกุลให้มันเลยก็ตาม ถ้าข้อความข้างในเป็น text มันก็คือ text file อยู่วันยังค่ำ</p>
<p>ปัญหามันอยู่ที่ไหนเหรอครับ ยังมีเว็บโปรแกรมเมอร์หลายคนที่ยังตั้งนามสกุลไฟล์เป็นพวกนี้อยู่ และมิหนำซ้ำ ยังเอาไป include ใช้งานจริงเสียด้วย ผมยกตัวอย่างกรณีของ php ละกันครับ ตัว php web server เอง (เช่น Apache) ปกติแล้วมันไม่ประมวลผลไฟล์นามสกุลพวกนี้หรอกครับ ยกเว้นแต่เราไป include ไฟล์พวกนั้นลงไปใน script ที่เราเขียน เช่นถ้าเป็น php มันก็จะประมวลผลไฟล์นามสกุลพวก .php, .php4, .php5 (หรืออะไรก็แล้วแต่ตามที่ตั้งไว้) ถ้าเราสั่ง include(&#8220;test.inc&#8221;) แบบนี้มันจะประมวลผล test.inc ให้ครับ แต่ถ้าเราลองเรียก test.inc ตรง ๆ ผ่าน browser มันไม่ประมวลผลหรอกครับ ทีนี้พอ server มันไม่ประมวลผล สิ่งที่มันคืนกลับมาให้เราเห็น มันก็คือข้อความข้างในไฟล์นั่นเอง ค่าต่าง ๆ ที่เราตั้งไว้เก็บไว้กะว่าจะดูคนเดียว ทั้ง username กับ password ของ database ทั้งโน่น ทั้งนี่ ตั้งหลายอย่าง ถูกเผยแพร่ไปง่าย ๆ ด้วยเหตุผลเพียงการตั้งนามสกุลไฟล์แบบนี้เท่านั้นเอง</p>
<p>พอมองเห็นปัญหาแล้วใช่มั๊ยครับ หลายคนตั้งนามสกุลไฟล์เป็นแบบนี้ เพื่อที่จะให้สื่อความหมายว่ามันเป็น include file นะ ก็ย่อว่า inc ไง หรือ config file นะ ก็ย่อว่า conf ไง ใช่ครับ มันสื่อ แต่มันไม่ได้เรื่องครับ อยากจะตั้งให้สื่อ แล้วยังจะให้ server ประมวลผล ก็ง่ายนิดเดียวครับ แค่เติมนามสกุลมันลงไปอีกหน่อยก็ได้ครับ เป็น .inc.php ก็ได้ เป็น .conf.php ก็ได้ สมัยไหนแล้ว ไม่ใช่ DOS นะครับ จะตั้งชื่อมีจุดหลาย ๆ จุดไม่ได้</p>
<p>แล้วคนอื่นจะรู้ได้ไงว่าเราตั้งนามสกุลไว้แบบนี้น่ะเหรอครับ ก็ตอนที่ server ล่ม หรือ script เจ๊งไงครับ เคยเห็นมั๊ยครับ ที่ script ทำงานไม่ถูกต้อง แล้วมัน report error ออกมา พร้อมชื่อไฟล์ที่มีปัญหา คิดว่ามันจะไม่มีวันเกิดขึ้นเลย 100% เหรอครับ กันไว้ก่อนดีกว่าครับ ดีกว่าจะมานั่งเสียใจทีหลังเพราะความเลินเล่อเล็ก ๆ น้อย ๆ</p>
<p>(entry นี้ เหมือนจะเป็นการบ่นเลยแฮะ แต่เพิ่งไปเจอคนตั้งชื่อไฟล์นามสกุลแบบนี้มา แล้ววันก่อนเว็บมันเจ๊งพอดี เลยเข้าไปดู เห็นอะไรหลายอย่างที่ไม่ควรให้เห็นเลยเชียว เฮ้อ&#8230; เห็นแล้วกลุ้ม เอามาบ่นหน่อยดีกว่า XD)</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2010%2F09%2F%25e0%25b9%2580%25e0%25b8%25a5%25e0%25b8%25b4%25e0%25b8%2581%25e0%25b9%2583%25e0%25b8%258a%25e0%25b9%2589%25e0%25b9%2580%25e0%25b8%25ab%25e0%25b8%25ad%25e0%25b8%25b0%25e0%25b9%2584%25e0%25b8%25ad%25e0%25b9%2589-inc-%25e0%25b8%2599%25e0%25b9%2588%25e0%25b8%25b0%2F&amp;title=%E0%B9%80%E0%B8%A5%E0%B8%B4%E0%B8%81%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B9%80%E0%B8%AB%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%AD%E0%B9%89%20.inc%20%E0%B8%99%E0%B9%88%E0%B8%B0" id="wpa2a_8"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2010/09/%e0%b9%80%e0%b8%a5%e0%b8%b4%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%80%e0%b8%ab%e0%b8%ad%e0%b8%b0%e0%b9%84%e0%b8%ad%e0%b9%89-inc-%e0%b8%99%e0%b9%88%e0%b8%b0/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Method Chaining ใน PHP ทำเองก็ได้ง่ายจัง</title>
		<link>http://blog.chonla.com/2009/09/method-chaining-%e0%b9%83%e0%b8%99-php-%e0%b8%97%e0%b8%b3%e0%b9%80%e0%b8%ad%e0%b8%87%e0%b8%81%e0%b9%87%e0%b9%84%e0%b8%94%e0%b9%89%e0%b8%87%e0%b9%88%e0%b8%b2%e0%b8%a2%e0%b8%88%e0%b8%b1%e0%b8%87/</link>
		<comments>http://blog.chonla.com/2009/09/method-chaining-%e0%b9%83%e0%b8%99-php-%e0%b8%97%e0%b8%b3%e0%b9%80%e0%b8%ad%e0%b8%87%e0%b8%81%e0%b9%87%e0%b9%84%e0%b8%94%e0%b9%89%e0%b8%87%e0%b9%88%e0%b8%b2%e0%b8%a2%e0%b8%88%e0%b8%b1%e0%b8%87/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 19:03:09 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Object Oriented]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Chainability]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=228</guid>
		<description><![CDATA[บทความนี้ได้แรงบันดาลใจมาจาก chainability ของ jQuery และ query builder ของ kohana (จริง ๆ ผมเข้าใจว่า query builder มีอยู่ใน php framework ตัวอื่นด้วย แต่พอดีท่านรุ่งจากบ้าน PHP.DeeServer.net ซึ่งแนะนำให้ผมรู้จักกับ kohana เค้าแนะนำตัวที่อยู่ใน kohana มาครับ) ไอเดียหลัก ๆ ของการทำ chaining ก็คือ การทำให้มันสามารถเรียกต่อกันได้เป็นทอด ๆ นั่นเอง ยกตัวอย่างใน jQuery ซึ่งมีคุณสมบัติที่เรียกว่า chainability อยู่ ทำให้เราสามารถเรียกคำสั่งได้แบบนี้ $("#submenu").addClass("whitemenu").show("slow"); จะเห็นได้ว่า เราสามารถเรียก .show ต่อเนื่องได้เลย นี่เองที่ทำให้เกิดการเรียกอย่างต่อเนื่อง หรือ การทำ Method chaining นั่นเอง ใน PHP เราสามารถทำให้ object มีคุณสมบัติเดียวกันนี้ได้เช่นกัน [...]]]></description>
			<content:encoded><![CDATA[<p>บทความนี้ได้แรงบันดาลใจมาจาก <a href="http://blog.chonla.com/2008/11/เมื่อฟ้าส่ง-chainability-มาให้กับ-jquery/" target="_blank" title="เมื่อฟ้าส่ง Chainability มาให้กับ jQuery">chainability</a> ของ <a href="http://www.jquery.com" target="_blank" title="jQuery - The Write Less, Do More, JavaScript Library">jQuery</a> และ query builder ของ <a href="http://www.kohanaphp.com/" target="_blank" title="Kohana - The swift PHP Framework">kohana</a> (จริง ๆ ผมเข้าใจว่า query builder มีอยู่ใน php framework ตัวอื่นด้วย แต่พอดีท่านรุ่งจากบ้าน <a href="http://php.deeserver.net" target="_blank" title="PHP.DeeServer.Net">PHP.DeeServer.net</a> ซึ่งแนะนำให้ผมรู้จักกับ kohana เค้าแนะนำตัวที่อยู่ใน kohana มาครับ)</p>
<p>ไอเดียหลัก ๆ ของการทำ chaining ก็คือ การทำให้มันสามารถเรียกต่อกันได้เป็นทอด ๆ นั่นเอง ยกตัวอย่างใน jQuery ซึ่งมีคุณสมบัติที่เรียกว่า chainability อยู่ ทำให้เราสามารถเรียกคำสั่งได้แบบนี้</p>
<pre name="code" class="js">
$("#submenu").addClass("whitemenu").show("slow");
</pre>
<p>จะเห็นได้ว่า เราสามารถเรียก .show ต่อเนื่องได้เลย นี่เองที่ทำให้เกิดการเรียกอย่างต่อเนื่อง หรือ การทำ Method chaining นั่นเอง<br />
<span id="more-228"></span></p>
<p>ใน PHP เราสามารถทำให้ object มีคุณสมบัติเดียวกันนี้ได้เช่นกัน เพียงแต่น่าเสียดายที่คุณสมบัตินี้ มีอยู่ใน PHP ตั้งแต่เวอร์ชั่น 5 ขึ้นไปเท่านั้น สำหรับคนที่ยังใช้ PHP4 อยู่ ผมต้องขอแสดงความเสียใจด้วยครับ ฮ่า ๆ และคาดว่าเหตุนี้เองที่ทำให้ kohana สามารถใช้งานได้กับ PHP5 ขึ้นไปเท่านั้น</p>
<p>หลักการง่าย ๆ ที่ทำให้เราสามารถทำ Method chaining ได้ก็คือ การเขียน class และทำการคืนค่าของ object มันเองกลับออกมาหลังจากที่จบ method ทำนองเดียวกับใน jQuery ตอนที่เขียน plugin </p>
<p>ตอนจบ เราก็จะทำการ return jQuery object กลับออกมาให้เช่นเดียวกัน</p>
<p>ลองมาดูตัวอย่างใน PHP กันดีกว่าครับ</p>
<pre name="code" class="js">
// php5 only
class Database
{
	private $link;

	private $table;
	private $field;
	private $condition;
	private $order;
	private $result;

	// connection functions
	function __construct($config)
	{
		$this->flush();
		$this->link = null;
		$this->connect($config["hostname"],
				$config["username"],
				$config["password"],
				$config["database"]);
	}

	function __destruct()
	{
		$this->disconnect();
	}

	function connect($host = "",
				$user = "",
				$password = "",
				$db = "")
	{
		if ($this->link !== null)
			$this->disconnect();

		$this->link = mysql_connect($host, $user, $password);

		if ($this->link === FALSE)
		{
			echo $this->err();
		}
		else
		{
			if ($db !== "")
			{
				return $this->db($db);
			}
		}
		return $this;
	}

	function disconnect()
	{	// break chain
		if ($this->link !== null)
			mysql_close($this->link);
		$this->link = null;
	}

	function db($db)
	{
		if (mysql_select_db($db, $this->link) === FALSE)
			echo $this->err();
		return $this;
	}

	function errno()
	{
		return mysql_errno($this->link);
	}

	function ok()
	{
		return ($this->errno() == 0);
	}

	function err()
	{	// break chain
		return mysql_error($this->link);
	}

	function execute($sql)
	{
		$this->result = mysql_query($sql, $this->link);
		return $this;
	}

	function records()
	{
		$result = array();
		if ($this->result !== FALSE)
		{
			while (($row = mysql_fetch_assoc($this->result)) !== FALSE)
			{
				$result[] = $row;
			}
		}
		return $result;
	}

	function flush()
	{
		$this->table = "";
		$this->field = "";
		$this->condition = "";
		$this->order = "";
		$this->result = null;
		return $this;
	}

	function safe($value)
	{
		if (!get_magic_quotes_gpc())
		{
			$value = addslashes($value);
		}
		return "'$value'";
	}

	function table($table)
	{
		$this->table = $table;
		return $this;
	}

	function field($field)
	{
		$this->field = $field;
		return $this;
	}

	function condition($condition)
	{
		if (is_array($condition))
		{
			$cond = array();
			foreach ($condition as $f => $v)
			{
				$cond[] = "($f = " . $this->safe($v) . ")";
			}
			$condition = implode(" AND ", $cond);
		}
		$this->condition = $condition;
		return $this;
	}

	function top($num = 1)
	{
		$field = $this->field;
		if ($field == "") $field = "*";
		$sql = "SELECT {$field} FROM {$this->table}";
		if ($this->condition !== "")
			$sql .= " WHERE {$this->condition}";
		if ($this->order !== "")
			$sql .= " ORDER BY {$this->order}";
		$sql .= " LIMIT 0, {$num}";
		return $this->execute($sql)->records();
	}

	function all()
	{
		$field = $this->field;
		if ($field == "") $field = "*";
		$sql = "SELECT {$field} FROM {$this->table}";
		if ($this->condition !== "")
			$sql .= " WHERE {$this->condition}";
		if ($this->order !== "")
			$sql .= " ORDER BY {$this->order}";
		return $this->execute($sql)->records();
	}

	function order($order)
	{
		$this->order = $order;
		return $this;
	}
}
</pre>
<p>code ด้านบนนี้ เป็น code ที่ผมทดสอบ โดยทำเป็นไอเดียเริ่มต้นง่าย ๆ สำหรับการทำ query builder จะเห็นได้ว่า หลาย ๆ method จะมีการ return ตัว object มันเอง ($this) ไอเดียหลักในการกำหนดว่า method ไหนที่ผม return หรือไม่ return $this ก็คือ มีความจำเป็นในการเรียก method ต่อจากนี้หรือไม่นั่นเอง</p>
<p>การใช้งานก็ไม่ได้ยุ่งยากอะไร</p>
<pre name="code" class="js">
$dbconf = array(
	"hostname" => "localhost",
	"username" => "root",
	"password" => "123456",
	"database" => "test"
);
$db = new Database($dbconf);
$rows = $db->table("products")
		->field("product_id, product_name")
		->condition(array(
				"product_group"=>"tyre",
				"product_model"=>"Eagle"))
		->top();
print_r($rows);
</pre>
<p>จากตัวอย่างด้านบน เป็นการ select หา product จาก table products โดยกำหนด criteria ในการค้นหาเป็น product_group = &#8216;tyre&#8217; และ product_model = &#8216;Eagle&#8217; โดยจะเลือกเอาเฉพาะ record แรกสุดเท่านั้น</p>
<p>เห็นมั๊ยครับ หลักการง่าย ๆ แค่ return $this เองครับ ที่สำคัญ อย่าลืมนะครับ PHP5 ขึ้นไปนะครับ</p>
<p>ขอให้สนุกกับการเขียนโปรแกรมครับ</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F09%2Fmethod-chaining-%25e0%25b9%2583%25e0%25b8%2599-php-%25e0%25b8%2597%25e0%25b8%25b3%25e0%25b9%2580%25e0%25b8%25ad%25e0%25b8%2587%25e0%25b8%2581%25e0%25b9%2587%25e0%25b9%2584%25e0%25b8%2594%25e0%25b9%2589%25e0%25b8%2587%25e0%25b9%2588%25e0%25b8%25b2%25e0%25b8%25a2%25e0%25b8%2588%25e0%25b8%25b1%25e0%25b8%2587%2F&amp;title=Method%20Chaining%20%E0%B9%83%E0%B8%99%20PHP%20%E0%B8%97%E0%B8%B3%E0%B9%80%E0%B8%AD%E0%B8%87%E0%B8%81%E0%B9%87%E0%B9%84%E0%B8%94%E0%B9%89%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B8%88%E0%B8%B1%E0%B8%87" id="wpa2a_10"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/09/method-chaining-%e0%b9%83%e0%b8%99-php-%e0%b8%97%e0%b8%b3%e0%b9%80%e0%b8%ad%e0%b8%87%e0%b8%81%e0%b9%87%e0%b9%84%e0%b8%94%e0%b9%89%e0%b8%87%e0%b9%88%e0%b8%b2%e0%b8%a2%e0%b8%88%e0%b8%b1%e0%b8%87/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>=== ไม่ใช่ &#8220;เท่ากัน&#8221; แต่ &#8220;เหมือนกัน&#8221;&#8230;อะไรเนี่ย!!</title>
		<link>http://blog.chonla.com/2009/08/%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%83%e0%b8%8a%e0%b9%88-%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b8%81%e0%b8%b1%e0%b8%99-%e0%b9%81%e0%b8%95%e0%b9%88-%e0%b9%80%e0%b8%ab%e0%b8%a1%e0%b8%b7/</link>
		<comments>http://blog.chonla.com/2009/08/%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%83%e0%b8%8a%e0%b9%88-%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b8%81%e0%b8%b1%e0%b8%99-%e0%b9%81%e0%b8%95%e0%b9%88-%e0%b9%80%e0%b8%ab%e0%b8%a1%e0%b8%b7/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 16:27:50 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Comparison]]></category>
		<category><![CDATA[Equal]]></category>
		<category><![CDATA[Identical]]></category>
		<category><![CDATA[Operator]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=211</guid>
		<description><![CDATA[วันนี้ผมจะแนะนำให้รู้จักกับการเปรียบเทียบด้วยเครื่องหมาย = ในอีกรูปแบบหนึ่ง โดยปกติแล้ว ทั้งใน PHP และ Javascript เวลาเราต้องการเปรียบเทียบค่าของตัวแปร 2 ตัว เราจะใช้เครื่องหมาย == (= ติดกัน 2 ตัว) ยกตัวอย่างเช่น // PHP // ตัวอย่างที่ 1 $a = 1; $b = 1; if ($a == $b) { // บล็อกนี้จะถูกทำเมื่อ $a มีค่าเท่ากับ $b echo "#1: a is equal to b\n"; } // ตัวอย่างที่ 2 $a = 1; $b = [...]]]></description>
			<content:encoded><![CDATA[<p>วันนี้ผมจะแนะนำให้รู้จักกับการเปรียบเทียบด้วยเครื่องหมาย = ในอีกรูปแบบหนึ่ง โดยปกติแล้ว ทั้งใน PHP และ Javascript เวลาเราต้องการเปรียบเทียบค่าของตัวแปร 2 ตัว เราจะใช้เครื่องหมาย == (= ติดกัน 2 ตัว) ยกตัวอย่างเช่น</p>
<pre name="code" class="js">
// PHP

// ตัวอย่างที่ 1
$a = 1;
$b = 1;
if ($a == $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a มีค่าเท่ากับ $b
    echo "#1: a is equal to b\n";
}

// ตัวอย่างที่ 2
$a = 1;
$b = "1";
if ($a == $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a มีค่าเท่ากับ $b
    echo "#2: a is equal to b\n";
}

// ตัวอย่างที่ 3
$a = 0;
$b = false;
if ($a == $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a มีค่าเท่ากับ $b
    echo "#3: a is equal to b\n";
}
</pre>
<p>ผลลัพธ์</p>
<pre name="code" class="js">
#1: a is equal to b
#2: a is equal to b
#3: a is equal to b
</pre>
<p><span id="more-211"></span><br />
การเปรียบเทียบแบบนี้ ถือเป็นการเปรียบเทียบค่ากันระหว่าง operand 2 ตัว โดยจะเปรียบเทียบเฉพาะค่าของมันเท่านั้น เมื่อผลของการเปรียบเทียบมีค่าเป็น true นั่นคือ operand ทั้งสองตัวนั้น &#8220;เท่ากัน&#8221; (equal) ซึ่งจะแตกต่างจาก ===</p>
<p>=== เป็นการเปรียบเทียบที่จะเปรียบเทียบทั้งค่า และชนิดของ operand ทั้งสองตัวนั้นด้วย เมื่อผลจากการเปรียบเทียบด้วย === มีค่าเป็น true เราถือว่า operand ทั้ง 2 ตัวนั้น &#8220;เหมือนกัน&#8221; (identical) นั่นเอง</p>
<p>ลองมาดูตัวอย่างกัน</p>
<pre name="code" class="js">
// PHP

// ตัวอย่างที่ 4
$a = 1;
$b = 1;
if ($a === $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a เหมือนกับ $b
    echo "#4: a is identical to b\n";
}

// ตัวอย่างที่ 5
$a = 1;
$b = "1";
if ($a === $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a เหมือนกับ $b
    echo "#5: a is identical to b\n";
}

// ตัวอย่างที่ 6
$a = 0;
$b = false;
if ($a === $b)
{
    // บล็อกนี้จะถูกทำเมื่อ $a เหมือนกับ $b
    echo "#6: a is identical to b\n";
}
</pre>
<p>ผลลัพธ์</p>
<pre name="code" class="js">
#4: a is identical to b
</pre>
<p><strong>หมายเหตุ</strong></p>
<ol>
<li>สำหรับการทำให้เป็น negative ด้วย ! นั้น เครื่องหมาย == เราจะใช้ != ในการเปรียบเทียบ &#8220;ไม่เท่ากัน&#8221; และ เครื่องหมาย === เราจะใช้ !== ในการเปรียบเทียบ &#8220;ไม่เหมือนกัน&#8221;</li>
<li>เครื่องหมาย === และ !== สามารถใช้ได้ทั้ง PHP และ Javascript</li>
<li>การใช้เครื่องหมาย = เพียงตัวเดียวนั้น หมายถึงการ &#8220;กำหนดค่าให้&#8221; (assign) ไม่ใช่การเปรียบเทียบ</li>
</ol>
<p><strong>อ้างอิง</strong></p>
<ul>
<li><a href="http://www.php.net/ternary">http://www.php.net/ternary</a></li>
<li><a href="http://www.w3schools.com/JS/js_comparisons.asp">http://www.w3schools.com/JS/js_comparisons.asp</a></li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F08%2F%25e0%25b9%2584%25e0%25b8%25a1%25e0%25b9%2588%25e0%25b9%2583%25e0%25b8%258a%25e0%25b9%2588-%25e0%25b9%2580%25e0%25b8%2597%25e0%25b9%2588%25e0%25b8%25b2%25e0%25b8%2581%25e0%25b8%25b1%25e0%25b8%2599-%25e0%25b9%2581%25e0%25b8%2595%25e0%25b9%2588-%25e0%25b9%2580%25e0%25b8%25ab%25e0%25b8%25a1%25e0%25b8%25b7%2F&amp;title=%3D%3D%3D%20%E0%B9%84%E0%B8%A1%E0%B9%88%E0%B9%83%E0%B8%8A%E0%B9%88%20%26%238220%3B%E0%B9%80%E0%B8%97%E0%B9%88%E0%B8%B2%E0%B8%81%E0%B8%B1%E0%B8%99%26%238221%3B%20%E0%B9%81%E0%B8%95%E0%B9%88%20%26%238220%3B%E0%B9%80%E0%B8%AB%E0%B8%A1%E0%B8%B7%E0%B8%AD%E0%B8%99%E0%B8%81%E0%B8%B1%E0%B8%99%26%238221%3B%26%238230%3B%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3%E0%B9%80%E0%B8%99%E0%B8%B5%E0%B9%88%E0%B8%A2%21%21" id="wpa2a_12"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/08/%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%83%e0%b8%8a%e0%b9%88-%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b8%81%e0%b8%b1%e0%b8%99-%e0%b9%81%e0%b8%95%e0%b9%88-%e0%b9%80%e0%b8%ab%e0%b8%a1%e0%b8%b7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>include? require? ใช้ตัวไหนดี ฤๅจะเด็ดทีเดียวเสียทั้งคู่</title>
		<link>http://blog.chonla.com/2009/06/include-require-%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%84%e0%b8%ab%e0%b8%99%e0%b8%94%e0%b8%b5-%e0%b8%a4%e0%b9%85%e0%b8%88%e0%b8%b0%e0%b9%80%e0%b8%94%e0%b9%87%e0%b8%94%e0%b8%97/</link>
		<comments>http://blog.chonla.com/2009/06/include-require-%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%84%e0%b8%ab%e0%b8%99%e0%b8%94%e0%b8%b5-%e0%b8%a4%e0%b9%85%e0%b8%88%e0%b8%b0%e0%b9%80%e0%b8%94%e0%b9%87%e0%b8%94%e0%b8%97/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 16:16:06 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[function]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[include]]></category>
		<category><![CDATA[include_once]]></category>
		<category><![CDATA[require]]></category>
		<category><![CDATA[require_once]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=199</guid>
		<description><![CDATA[คำถามง่าย ๆ ว่า ระหว่าง include กับ require ใน PHP นั้น ต่างกันตรงไหน สำหรับคนที่ใช้งานบ่อย ๆ บางคนอาจจะไม่เคยสังเกต ความจริงแล้ว ทั้ง 2 ฟังก์ชั่นนี้ ต่างก็ทำหน้าที่เหมือน ๆ กัน คือ ทำการรวมเอาไฟล์ที่ระบุ และประมวลผลไฟล์นั้นเข้ามา (include and evaluate) ส่วนที่แตกต่างกันจะแตกต่างกันอยู่จุดเดียว ก็คือการจัดการกับ Error ที่เกิดขึ้น โดยที่ทั้งสองฟังก์ชั่นเวลาเกิดปัญหาจะแสดง warning ออกมาเหมือนกัน โดยที่ require จะแสดงออกมาเป็น fatal error แต่ include จะแสดงเป็น warning เฉย ๆ นั่นหมายถึงว่าถ้าเราใช้ require แล้วเวลาเกิด error (เช่น ไม่มีไฟล์ที่ต้องการ) ก็จะเกิดเป็น fatal error และจะไม่ทำการประมวลผลส่วนที่เหลือของหน้าต่อ [...]]]></description>
			<content:encoded><![CDATA[<p>คำถามง่าย ๆ ว่า ระหว่าง include กับ require ใน PHP นั้น ต่างกันตรงไหน สำหรับคนที่ใช้งานบ่อย ๆ บางคนอาจจะไม่เคยสังเกต</p>
<p>ความจริงแล้ว ทั้ง 2 ฟังก์ชั่นนี้ ต่างก็ทำหน้าที่เหมือน ๆ กัน คือ ทำการรวมเอาไฟล์ที่ระบุ และประมวลผลไฟล์นั้นเข้ามา (include and evaluate) ส่วนที่แตกต่างกันจะแตกต่างกันอยู่จุดเดียว ก็คือการจัดการกับ Error ที่เกิดขึ้น</p>
<p><span id="more-199"></span>โดยที่ทั้งสองฟังก์ชั่นเวลาเกิดปัญหาจะแสดง warning ออกมาเหมือนกัน โดยที่ require จะแสดงออกมาเป็น fatal error แต่ include จะแสดงเป็น warning เฉย ๆ นั่นหมายถึงว่าถ้าเราใช้ require แล้วเวลาเกิด error (เช่น ไม่มีไฟล์ที่ต้องการ) ก็จะเกิดเป็น fatal error และจะไม่ทำการประมวลผลส่วนที่เหลือของหน้าต่อ ในขณะที่ warning จะแสดงเป็น warning และจะยังคงประมวลผลส่วนที่เหลือของหน้าต่อไป</p>
<p>หลักการนี้ได้รวมถึงฟังก์ชั่น include_once และ require_once ด้วยครับ (** include_once และ require_once จะเป็นการเอาไฟล์มารวมเพียงครั้งเดียว ถึงแม้่จะเรียกหลายครั้งก็ตาม **)</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F06%2Finclude-require-%25e0%25b9%2583%25e0%25b8%258a%25e0%25b9%2589%25e0%25b8%2595%25e0%25b8%25b1%25e0%25b8%25a7%25e0%25b9%2584%25e0%25b8%25ab%25e0%25b8%2599%25e0%25b8%2594%25e0%25b8%25b5-%25e0%25b8%25a4%25e0%25b9%2585%25e0%25b8%2588%25e0%25b8%25b0%25e0%25b9%2580%25e0%25b8%2594%25e0%25b9%2587%25e0%25b8%2594%25e0%25b8%2597%2F&amp;title=include%3F%20require%3F%20%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%95%E0%B8%B1%E0%B8%A7%E0%B9%84%E0%B8%AB%E0%B8%99%E0%B8%94%E0%B8%B5%20%E0%B8%A4%E0%B9%85%E0%B8%88%E0%B8%B0%E0%B9%80%E0%B8%94%E0%B9%87%E0%B8%94%E0%B8%97%E0%B8%B5%E0%B9%80%E0%B8%94%E0%B8%B5%E0%B8%A2%E0%B8%A7%E0%B9%80%E0%B8%AA%E0%B8%B5%E0%B8%A2%E0%B8%97%E0%B8%B1%E0%B9%89%E0%B8%87%E0%B8%84%E0%B8%B9%E0%B9%88" id="wpa2a_14"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/06/include-require-%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%84%e0%b8%ab%e0%b8%99%e0%b8%94%e0%b8%b5-%e0%b8%a4%e0%b9%85%e0%b8%88%e0%b8%b0%e0%b9%80%e0%b8%94%e0%b9%87%e0%b8%94%e0%b8%97/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ไอเดีย Template Engine แบบ Basic</title>
		<link>http://blog.chonla.com/2009/05/%e0%b9%84%e0%b8%ad%e0%b9%80%e0%b8%94%e0%b8%b5%e0%b8%a2-template-%e0%b9%81%e0%b8%9a%e0%b8%9a-basic/</link>
		<comments>http://blog.chonla.com/2009/05/%e0%b9%84%e0%b8%ad%e0%b9%80%e0%b8%94%e0%b8%b5%e0%b8%a2-template-%e0%b9%81%e0%b8%9a%e0%b8%9a-basic/#comments</comments>
		<pubDate>Thu, 14 May 2009 15:41:49 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[Template Engine]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Template]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=171</guid>
		<description><![CDATA[ใน framework ที่มีการแยก View ออกมาอย่างชัดเจน อย่างเช่น MVC จะมีการใช้ Template เข้ามาเป็นตัวช่วยในการช่วยแสดงผล ไม่ว่าจะเป็นการใช้ Template Engine อย่างเช่น smarty เป็นต้น ทีนี้ ผมก็มาคิด ๆ ดูว่าไอ้เจ้า Template เนี่ย มันมีไอเดียการทำงานยังไง ลองมาดูกัน หลักการง่าย ๆ ของการทำ Template คือ การแยกแนวคิดให้ตัว Template ทำหน้าที่แสดงผลอย่างเดียว โดยไม่มี Logic อื่น ๆ มาเกี่ยวข้อง เราอาจจะมี condition บางอย่างอยู่ใน template ได้ แต่ก็เฉพาะในส่วนที่เกี่ยวข้องกับการแสดงผลเท่านั้น ดังนั้น สิ่งที่จำเป็นก่อนการแสดงผลนั่นก็คือ การเตรียมข้อมูลที่จะแสดงให้พร้อมนั่นเอง ต่อจากนั้นเราก็นำข้อมูลที่เราเตรียมไว้ ไปยัดใส่ template ที่เราเตรียมไว้ เป็นอันเรียบร้อย เรามาสร้าง template engine แบบง่ายที่สุดในโลกกันดีกว่า function [...]]]></description>
			<content:encoded><![CDATA[<p>ใน framework ที่มีการแยก View ออกมาอย่างชัดเจน อย่างเช่น MVC จะมีการใช้ Template เข้ามาเป็นตัวช่วยในการช่วยแสดงผล ไม่ว่าจะเป็นการใช้ Template Engine อย่างเช่น <a title="Smarty Template Engine" href="http://www.smarty.net/" target="_blank">smarty</a> เป็นต้น</p>
<p>ทีนี้ ผมก็มาคิด ๆ ดูว่าไอ้เจ้า Template เนี่ย มันมีไอเดียการทำงานยังไง ลองมาดูกัน</p>
<p><span id="more-171"></span>หลักการง่าย ๆ ของการทำ Template คือ การแยกแนวคิดให้ตัว Template ทำหน้าที่แสดงผลอย่างเดียว โดยไม่มี Logic อื่น ๆ มาเกี่ยวข้อง เราอาจจะมี condition บางอย่างอยู่ใน template ได้ แต่ก็เฉพาะในส่วนที่เกี่ยวข้องกับการแสดงผลเท่านั้น ดังนั้น สิ่งที่จำเป็นก่อนการแสดงผลนั่นก็คือ การเตรียมข้อมูลที่จะแสดงให้พร้อมนั่นเอง ต่อจากนั้นเราก็นำข้อมูลที่เราเตรียมไว้ ไปยัดใส่ template ที่เราเตรียมไว้ เป็นอันเรียบร้อย</p>
<p>เรามาสร้าง template engine แบบง่ายที่สุดในโลกกันดีกว่า</p>
<pre name="code" class="js">
function apply_template($data, $template)
{
    ob_start();
    include ($template);
    $output = ob_get_clean();
    return $output;
} 
</pre>
<p>ดูเหมือนง่ายมั๊ยครับ แค่ไม่กี่บรรทัดเอง ส่วนของ template file เราก็จะมีตัวแปรไว้ใช้งานตัวนึง ชื่อว่า $data นั่นเองครับ เวลาเราส่งค่าเข้า template ก็ให้ส่งผ่านตัวแปรตัวเดียวครับ (อาจจะทำเป็น array หรือ object ก็ได้ครับ)</p>
<p>ลองดูตัวอย่างใน <a title="LIVE DEMO : Basic Template Engine" href="http://sandbox.chonla.com/template/" target="_blank">LIVE DEMO</a> นะครับ</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F05%2F%25e0%25b9%2584%25e0%25b8%25ad%25e0%25b9%2580%25e0%25b8%2594%25e0%25b8%25b5%25e0%25b8%25a2-template-%25e0%25b9%2581%25e0%25b8%259a%25e0%25b8%259a-basic%2F&amp;title=%E0%B9%84%E0%B8%AD%E0%B9%80%E0%B8%94%E0%B8%B5%E0%B8%A2%20Template%20Engine%20%E0%B9%81%E0%B8%9A%E0%B8%9A%20Basic" id="wpa2a_16"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/05/%e0%b9%84%e0%b8%ad%e0%b9%80%e0%b8%94%e0%b8%b5%e0%b8%a2-template-%e0%b9%81%e0%b8%9a%e0%b8%9a-basic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upload progress อัพไปเท่าไหร่แล้ว บอกหน่อยซิ</title>
		<link>http://blog.chonla.com/2009/04/upload-progress-%e0%b8%ad%e0%b8%b1%e0%b8%9e%e0%b9%84%e0%b8%9b%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b9%84%e0%b8%ab%e0%b8%a3%e0%b9%88%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7-%e0%b8%9a%e0%b8%ad%e0%b8%81/</link>
		<comments>http://blog.chonla.com/2009/04/upload-progress-%e0%b8%ad%e0%b8%b1%e0%b8%9e%e0%b9%84%e0%b8%9b%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b9%84%e0%b8%ab%e0%b8%a3%e0%b9%88%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7-%e0%b8%9a%e0%b8%ad%e0%b8%81/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 18:35:26 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[Progress]]></category>
		<category><![CDATA[Upload]]></category>
		<category><![CDATA[อัพโหลด]]></category>
		<category><![CDATA[เปอร์เซนต์]]></category>
		<category><![CDATA[แถบ]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=163</guid>
		<description><![CDATA[ลองแวะไปดูที่ http://www.zidoupload.com แล้วลองอัพโหลดไฟล์อะไรก็ได้ซักไฟล์นึง จะเห็นว่าระหว่างที่รอ มันจะมีการแสดงผลเป็นแถบว่าตอนนี้เราอัพโหลดไปแล้วกี่เปอร์เซนต์ รวมถึงยังบอกอีกว่า Transfer rate เป็นเท่าไหร่ ตรงนี้แหละครับที่ผมจะมาพูดถึงในวันนี้ การจะทำ Upload progress ด้วย PHP นั้น ส่วนประกอบที่ผมเลือกใช้จะประกอบด้วยส่วนหลัก ๆ อยู่ 3 ส่วนครับ คือ APC ย่อมาจาก Alternative PHP Cache ครับ ซึ่งจะมี library ที่ผมต้องการ นั่นคือ apc_fetch() ครับ Server ที่เราใช้จะต้องสนับสนุน APC ครับ ซึ่งเป็น PECL เข้าไปดาวน์โหลดได้จาก http://pecl.php.net/package/apc ครับ Ajax ในที่นี้ ผมใช้ Ajax ควบคู่กับ JSON ครับ Upload form ก็จะเป็น Form Upload ธรรมดานี่แหละครับ [...]]]></description>
			<content:encoded><![CDATA[<p>ลองแวะไปดูที่ <a title="ZidoUpload.com สุดยอดสังคมเพื่อการแบ่งปัน" href="http://www.zidoupload.com" target="_blank">http://www.zidoupload.co</a>m แล้วลองอัพโหลดไฟล์อะไรก็ได้ซักไฟล์นึง จะเห็นว่าระหว่างที่รอ มันจะมีการแสดงผลเป็นแถบว่าตอนนี้เราอัพโหลดไปแล้วกี่เปอร์เซนต์ รวมถึงยังบอกอีกว่า Transfer rate เป็นเท่าไหร่ ตรงนี้แหละครับที่ผมจะมาพูดถึงในวันนี้<br />
<span id="more-163"></span><br />
การจะทำ Upload progress ด้วย PHP นั้น ส่วนประกอบที่ผมเลือกใช้จะประกอบด้วยส่วนหลัก ๆ อยู่ 3 ส่วนครับ คือ</p>
<ol>
<li>APC ย่อมาจาก Alternative PHP Cache ครับ ซึ่งจะมี library ที่ผมต้องการ นั่นคือ apc_fetch() ครับ Server ที่เราใช้จะต้องสนับสนุน APC ครับ ซึ่งเป็น PECL เข้าไปดาวน์โหลดได้จาก <a title="APC Information" href="http://pecl.php.net/package/apc" target="_blank">http://pecl.php.net/package/apc</a> ครับ</li>
<li>Ajax ในที่นี้ ผมใช้ Ajax ควบคู่กับ JSON ครับ</li>
<li>Upload form ก็จะเป็น Form Upload ธรรมดานี่แหละครับ กำหนด enctypemultipart/form-data ให้เรียบร้อย และ method เป็น POST ให้เรียบร้อยเช่นกันครับ</li>
</ol>
<p>สำหรับไฟล์ที่จำเป็นในการทำ Upload Progress ด้วยวิธีนี้ ก็จะมี 3 ส่วนเช่นกัน ง่าย ๆ ตามนี้เลยครับ</p>
<ol>
<li>Upload Form จะเป็นหน้า Page ที่ User เห็นครับ เอาไว้สำหรับให้ User Browse File และกด Submit ครับ</li>
<li>Upload จะเป็นหน้า Page ที่เอาไว้สำหรับ Upload เลยครับ ในหน้านี้ ให้ทำการอัพโหลดเหมือนปกติครับ คือมีการ move_uploaded_file() อะไรเหมือนปกติืืทุกอย่างครับ</li>
<li>Progress จะเป็นส่วนที่เอาไว้สำหรับให้หน้า Form Upload มา poll ค่า status ของการ Upload ครับ ส่วนนี้แหละครับ ที่จะเป็นตัว return กลับไปว่า อัพโหลดอะไรได้ยังไงเท่าไหร่แล้วครับ</li>
</ol>
<p> </p>
<p><strong>Upload Form</strong></p>
<p>ทีนี้ เมื่อเรามีทุกอย่างพร้อม เราก็จะทำการกำหนด key สำหรับ Upload session เพื่อให้การ Poll ถามข้อมูลนั้นทำได้ถูกต้องครับ การกำหนดเราทำได้โดยการใส่ input hidden ที่ชื่อ APC_UPLOAD_PROGRESS ให้มีค่าเป็น key ที่เราต้องการครับ ผมสมมติให้มีค่าเป็น &#8220;abcd&#8221; ดังนั้น form ที่เราได้ควรจะมีหน้าตาประมาณแบบนี้ครับ (ชื่อ APC_UPLOAD_PROGRESS เราสามารถเปลี่ยนได้ใน php.ini ครับ)</p>
<p> </p>
<pre class="html" name="code">&lt;form enctype="multipart/form-data" action="upload.php" method="post"&gt;
    &lt;input type="hidden" name="APC_UPLOAD_PROGRESS" value="abcd"&gt;
    &lt;input name="upfile" type="file"&gt;&lt;/span&gt;
    &lt;input type="submit" value="Upload"&gt;
&lt;/form&gt;</pre>
<p> </p>
<p><strong>Upload</strong></p>
<p>ในส่วนนี้ผมไม่พูดถึงนะครับ ทำการอัพโหลดไฟล์ตามปกติเลยครับ ในกรณีที่ไฟล์ใหญ่มาก อย่าลืม set ให้ไม่ต้องมี timeout ด้วย function set_time_limit(0) ด้วยนะครับ</p>
<p> </p>
<p><strong>Progress</strong></p>
<p>สำหรับ Progress ไฟล์นั้น จะมีหน้าตาประมาณนี้ครับ</p>
<pre class="php" name="code">&lt;?php
header("content-type:application/json");
$stat = apc_fetch('upload_abcd');
if ($stat)
{
    if (!isset($stat["total"])) $stat["total"] = 0;
    if (!isset($stat["current"])) $stat["current"] = 0;
    if (!isset($stat["rate"])) $stat["rate"] = 0;
    if (!isset($stat["cancel_upload"])) $stat["cancel_upload"] = 0;
    if (!isset($stat["done"])) $stat["done"] = 0;
    f (!isset($stat["filename"])) $stat["filename"] = "";
    printf("[%0d,%0d,%0d,%0d,%0d,\"%s\"]",
    $stat["total"] ,
    $stat["current"] ,
    $stat["rate"] ,
    $stat["cancel_upload"] ,
    $stat["done"],
    addslashes($stat["filename"]));
}
else
{
    echo "null";
}
?&gt;</pre>
<p> </p>
<p>สิ่งที่เราต้องทำคือ ทำการ poll ข้อมูลการอัพโหลดของ key &#8220;abcd&#8221; จาก server เราก็ทำได้โดยเรียก function apc_fetch และกำหนด parameter เป็น string ขึ้นต้นด้วย &#8220;upload_&#8221; และตามด้วย key ของเรา คือ &#8220;abcd&#8221;</p>
<p>ค่าที่ return มาจาก apc_fetch จะได้เป็น associative array โดยมี key ที่เราจะเอามาใช้งานคือ</p>
<ul>
<li>total เป็นขนาดไฟล์</li>
<li>current เป็นขนาดไฟล์ที่อัพโหลดได้แล้ว</li>
<li>rate คือความเร็วในการอัพโหลดครับ</li>
<li>filename เป็นชื่อไฟล์ในเครื่องเราครับ (เช่น C:\Download\file.txt)</li>
</ul>
<p>คราวนี้ เราก็แค่ใช้ ajax มา poll ค่าเหล่านี้ออกไปแสดงเท่านั้นเองครับ ทีนี้ต้องพึ่งฝีมือ dhtml กับ graphic ของคุณเองแล้วล่ะครับ ว่าจะทำ progress bar ออกมาได้สวยแค่ไหน</p>
<p> </p>
<p>บทความนี้ ผมไม่มี LIVE DEMO แต่มีตัวอย่างให้ลองดาวน์โหลดไปทดสอบกันได้ครับ <a href="http://sandbox.chonla.com/uploadprogress/" title="SAMPLE DOWNLOAD : Download Progress">ดาวน์โหลด</a> กับเว็บที่ผมทำให้เอาไปใช้งานจริงครับ แวะลองไปทดสอบและใช้บริการกันได้ที่ <a title="ZidoUpload.com สุดยอดสังคมเพื่อการแบ่งปัน" href="http://www.zidoupload.com" target="_blank">http://www.zidoupload.com</a> ครับ</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F04%2Fupload-progress-%25e0%25b8%25ad%25e0%25b8%25b1%25e0%25b8%259e%25e0%25b9%2584%25e0%25b8%259b%25e0%25b9%2580%25e0%25b8%2597%25e0%25b9%2588%25e0%25b8%25b2%25e0%25b9%2584%25e0%25b8%25ab%25e0%25b8%25a3%25e0%25b9%2588%25e0%25b9%2581%25e0%25b8%25a5%25e0%25b9%2589%25e0%25b8%25a7-%25e0%25b8%259a%25e0%25b8%25ad%25e0%25b8%2581%2F&amp;title=Upload%20progress%20%E0%B8%AD%E0%B8%B1%E0%B8%9E%E0%B9%84%E0%B8%9B%E0%B9%80%E0%B8%97%E0%B9%88%E0%B8%B2%E0%B9%84%E0%B8%AB%E0%B8%A3%E0%B9%88%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%20%E0%B8%9A%E0%B8%AD%E0%B8%81%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%A2%E0%B8%8B%E0%B8%B4" id="wpa2a_18"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/04/upload-progress-%e0%b8%ad%e0%b8%b1%e0%b8%9e%e0%b9%84%e0%b8%9b%e0%b9%80%e0%b8%97%e0%b9%88%e0%b8%b2%e0%b9%84%e0%b8%ab%e0%b8%a3%e0%b9%88%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7-%e0%b8%9a%e0%b8%ad%e0%b8%81/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>หมายเลขบัตรประชาชน? สร้างเองดีกว่า</title>
		<link>http://blog.chonla.com/2009/04/%e0%b8%ab%e0%b8%a1%e0%b8%b2%e0%b8%a2%e0%b9%80%e0%b8%a5%e0%b8%82%e0%b8%9a%e0%b8%b1%e0%b8%95%e0%b8%a3%e0%b8%9b%e0%b8%a3%e0%b8%b0%e0%b8%8a%e0%b8%b2%e0%b8%8a%e0%b8%99-%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2/</link>
		<comments>http://blog.chonla.com/2009/04/%e0%b8%ab%e0%b8%a1%e0%b8%b2%e0%b8%a2%e0%b9%80%e0%b8%a5%e0%b8%82%e0%b8%9a%e0%b8%b1%e0%b8%95%e0%b8%a3%e0%b8%9b%e0%b8%a3%e0%b8%b0%e0%b8%8a%e0%b8%b2%e0%b8%8a%e0%b8%99-%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 08:14:57 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Utility]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=155</guid>
		<description><![CDATA[สาเหตุที่ผมเขียนบทความนี้ขึ้นมา เพราะว่ามันจะมีบางช่วงเวลาที่ผมจำเป็นต้องใช้หมายเลขบัตรประชาชนในการทำอะไรหลาย ๆ อย่าง ไม่ว่าจะเป็นเรื่องของการทำระบบ verify หมายเลขบัตรประชาชน หรือเอาไปใช้สมัครโน่นสมัครนี่ บางครั้งผมแค่อยากลองเฉย ๆ แต่ไม่ได้อยากใช้หมายเลขบัตรของผมจริง ๆ ด้วยเหตุผลด้านความปลอดภัยของผมเอง ผมเลยลองสร้างหมายเลขบัตรประชาชนจากอัลกอริธึมในการตรวจสอบหมายเลขบัตรประชาชนขึ้นมา อัลกอริธึมในการตรวจสอบหมายเลขบัตรประชาชน สามารถหาได้ตามเว็บทั่ว ๆ ไป ที่ผมได้มาก็จะประมาณนี้ครับ (Javascript) function validate_thai_citizen_id(id) { var b = 0; if (id.length &#60; 13) return false; checksum = id.substring(12, 13); for (var i = 0; i &#60; 12; i++) { b += parseInt(id.substring(i, i+1)) * (13 - i); [...]]]></description>
			<content:encoded><![CDATA[<p>สาเหตุที่ผมเขียนบทความนี้ขึ้นมา เพราะว่ามันจะมีบางช่วงเวลาที่ผมจำเป็นต้องใช้หมายเลขบัตรประชาชนในการทำอะไรหลาย ๆ อย่าง ไม่ว่าจะเป็นเรื่องของการทำระบบ verify หมายเลขบัตรประชาชน หรือเอาไปใช้สมัครโน่นสมัครนี่ บางครั้งผมแค่อยากลองเฉย ๆ แต่ไม่ได้อยากใช้หมายเลขบัตรของผมจริง ๆ ด้วยเหตุผลด้านความปลอดภัยของผมเอง ผมเลยลองสร้างหมายเลขบัตรประชาชนจากอัลกอริธึมในการตรวจสอบหมายเลขบัตรประชาชนขึ้นมา</p>
<p><span id="more-155"></span>อัลกอริธึมในการตรวจสอบหมายเลขบัตรประชาชน สามารถหาได้ตามเว็บทั่ว ๆ ไป ที่ผมได้มาก็จะประมาณนี้ครับ (Javascript)</p>
<pre name="code" class="js">
function validate_thai_citizen_id(id)
{
    var b = 0;
    if (id.length &lt; 13) return false;
    checksum = id.substring(12, 13);
    for (var i = 0; i &lt; 12; i++)
    {
        b += parseInt(id.substring(i, i+1)) * (13 - i);
    }
    tmp = 11 - (b % 11);
    switch(tmp)
    {
        case 11: check = 1; break;
        case 10: check = 0; break;
        default: check = tmp;
    }
    return (check == checksum);
}
</pre>
<p>จาก code ด้านบน เราจะเห็นได้ว่าส่วนที่สำคัญที่สุดคือ digit สุดท้าย ซึ่งจะทำหน้าที่เป็น checksum digit ซึ่งเราสามารถคำนวณได้จาก 12 digits แรก</p>
<p>เมื่อเราเอามาจัดการเขียนให้เป็นเรื่องเป็นราวจะได้แบบนี้ครับ</p>
<pre name="code" class="php">
function generate_thai_citizen_id()
{
	$checksum = 0;
	$b = 0;
	$r = 0;
	$t = "";
	mt_srand();
	for ($i = 0; $i < 12; $i ++)
	{
		$r = mt_rand(0, 9);
		$b += $r * (13 - $i);
		$t .= "$r";
	}
	$tmp = 11 - ($b % 11);
	switch($tmp)
	{
		case 11: $check = 1; break;
		case 10: $check = 0; break;
		default: $check = $tmp;
	}
	$t .= $check;
	return $t;
}
</pre>
<p>Code ด้านบนนี้ผมพอร์ตมาจาก Javascript version ที่ผมทำไว้ให้เป็น PHP ครับ</p>
<p>ลองดูหน้าที่ทำเสร็จแล้ว (PHP) ได้ที่ <a title="LIVE DEMO: Randomly create citizen ID" href="http://sandbox.chonla.com/citizenid/" target="_blank">LIVE DEMO</a> เลยครับ</p>
<p>ปล. หมายเลขบัตรประชาชนที่สร้างจาก <a title="LIVE DEMO: Randomly create citizen ID" href="http://sandbox.chonla.com/citizenid/" target="_blank">LIVE DEMO</a> สามารถนำไปใช้ได้จริงนะครับ ใช้ให้ถูกที่ถูกกฏหมายนะครับ<br />
ปล. อีกที วันที่ 9 ก.ย. 52 ผมแก้ไข code ที่เป็น เวอร์ชั่น php ให้ถูกต้องครับ มีบักนิดหน่อย</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.chonla.com%2F2009%2F04%2F%25e0%25b8%25ab%25e0%25b8%25a1%25e0%25b8%25b2%25e0%25b8%25a2%25e0%25b9%2580%25e0%25b8%25a5%25e0%25b8%2582%25e0%25b8%259a%25e0%25b8%25b1%25e0%25b8%2595%25e0%25b8%25a3%25e0%25b8%259b%25e0%25b8%25a3%25e0%25b8%25b0%25e0%25b8%258a%25e0%25b8%25b2%25e0%25b8%258a%25e0%25b8%2599-%25e0%25b8%25aa%25e0%25b8%25a3%25e0%25b9%2589%25e0%25b8%25b2%2F&amp;title=%E0%B8%AB%E0%B8%A1%E0%B8%B2%E0%B8%A2%E0%B9%80%E0%B8%A5%E0%B8%82%E0%B8%9A%E0%B8%B1%E0%B8%95%E0%B8%A3%E0%B8%9B%E0%B8%A3%E0%B8%B0%E0%B8%8A%E0%B8%B2%E0%B8%8A%E0%B8%99%3F%20%E0%B8%AA%E0%B8%A3%E0%B9%89%E0%B8%B2%E0%B8%87%E0%B9%80%E0%B8%AD%E0%B8%87%E0%B8%94%E0%B8%B5%E0%B8%81%E0%B8%A7%E0%B9%88%E0%B8%B2" id="wpa2a_20"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2009/04/%e0%b8%ab%e0%b8%a1%e0%b8%b2%e0%b8%a2%e0%b9%80%e0%b8%a5%e0%b8%82%e0%b8%9a%e0%b8%b1%e0%b8%95%e0%b8%a3%e0%b8%9b%e0%b8%a3%e0%b8%b0%e0%b8%8a%e0%b8%b2%e0%b8%8a%e0%b8%99-%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

