<?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; chonla</title>
	<atom:link href="http://blog.chonla.com/author/admin/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>พิมพ์ไปทำตัวใหญ่ไปไม่ยากอย่างที่คิด</title>
		<link>http://blog.chonla.com/2011/12/%e0%b8%9e%e0%b8%b4%e0%b8%a1%e0%b8%9e%e0%b9%8c%e0%b9%84%e0%b8%9b%e0%b8%97%e0%b8%b3%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%83%e0%b8%ab%e0%b8%8d%e0%b9%88%e0%b9%84%e0%b8%9b%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b8%a2/</link>
		<comments>http://blog.chonla.com/2011/12/%e0%b8%9e%e0%b8%b4%e0%b8%a1%e0%b8%9e%e0%b9%8c%e0%b9%84%e0%b8%9b%e0%b8%97%e0%b8%b3%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%83%e0%b8%ab%e0%b8%8d%e0%b9%88%e0%b9%84%e0%b8%9b%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b8%a2/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 06:32:39 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[capitalize]]></category>
		<category><![CDATA[lowercase]]></category>
		<category><![CDATA[uppercase]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=345</guid>
		<description><![CDATA[ในภาษาอังกฤษ การทำให้ตัวอักษรเป็นตัวอักษรใหญ่ (เช่น a-&#62;A) เรียกว่าการทำให้เป็น Uppercase แต่ถ้าทำให้เป็นตรงกันข้าม เราเรียกว่าทำ Lowercase แต่ในหลาย ๆ ครั้ง เราจะเห็นการทำตัวอักษรเฉพาะตัวแรกให้เป็นตัวใหญ่ ส่วนที่เหลือเป็นตัวเล็ก แบบนี้เราจะเรียกว่า Capitalize ไม่ว่าจะเป็นการทำ Uppercase, Lowercase หรือ Capitalize จริง ๆ แล้วไม่ใช่เรื่องยุ่งยากอะไร หลาย ๆ คนแก้ปัญหานี้ด้วยวิธีการเขียน Javascript มาดักตอนที่พิมพ์ แล้วปรับแก้เป็นตัวที่ต้องการ ในความจริงแล้ว เรายังสามารถทำได้อีกหลายวิธี มีวิธีหนึ่งที่ผมคิดว่าโคตรง่าย นั่นคือการใช้ CSS มาช่วยนั่นเอง การใช้ CSS มาเปลี่ยนตัวอักษรนั้น ทำได้โดยการใช้ style ที่ชื่อว่า text-transform โดยกำหนดค่าเป็นแบบนี้ กำหนดเป็น uppercase เพื่อให้ตัวอักษรที่เราต้องการเป็นตัวใหญ่ทั้งหมด กำหนดเป็น lowercase เพื่อให้ตัวอักษรที่เราต้องการเป็นตัวเล็กทั้งหมด กำหนดเป็น capitalize เพื่อให้ตัวอักษรตัวแรกของคำที่เราต้องการเป็นตัวใหญ่ (ที่เหลือเป็นตัวเล็ก) วิธีนี้ใช้ได้กับทุก [...]]]></description>
			<content:encoded><![CDATA[<p>ในภาษาอังกฤษ การทำให้ตัวอักษรเป็นตัวอักษรใหญ่ (เช่น a-&gt;A) เรียกว่าการทำให้เป็น Uppercase แต่ถ้าทำให้เป็นตรงกันข้าม เราเรียกว่าทำ Lowercase แต่ในหลาย ๆ ครั้ง เราจะเห็นการทำตัวอักษรเฉพาะตัวแรกให้เป็นตัวใหญ่ ส่วนที่เหลือเป็นตัวเล็ก แบบนี้เราจะเรียกว่า Capitalize</p>
<p><span id="more-345"></span></p>
<p>ไม่ว่าจะเป็นการทำ Uppercase, Lowercase หรือ Capitalize จริง ๆ แล้วไม่ใช่เรื่องยุ่งยากอะไร หลาย ๆ คนแก้ปัญหานี้ด้วยวิธีการเขียน Javascript มาดักตอนที่พิมพ์ แล้วปรับแก้เป็นตัวที่ต้องการ ในความจริงแล้ว เรายังสามารถทำได้อีกหลายวิธี มีวิธีหนึ่งที่ผมคิดว่าโคตรง่าย นั่นคือการใช้ CSS มาช่วยนั่นเอง</p>
<p>การใช้ CSS มาเปลี่ยนตัวอักษรนั้น ทำได้โดยการใช้ style ที่ชื่อว่า text-transform โดยกำหนดค่าเป็นแบบนี้</p>
<ul>
<li>กำหนดเป็น uppercase เพื่อให้ตัวอักษรที่เราต้องการเป็นตัวใหญ่ทั้งหมด</li>
<li>กำหนดเป็น lowercase เพื่อให้ตัวอักษรที่เราต้องการเป็นตัวเล็กทั้งหมด</li>
<li>กำหนดเป็น capitalize เพื่อให้ตัวอักษรตัวแรกของคำที่เราต้องการเป็นตัวใหญ่ (ที่เหลือเป็นตัวเล็ก)</li>
</ul>
<p>วิธีนี้ใช้ได้กับทุก ๆ element รวมถึง input และ textarea ด้วย นั่นหมายถึงเราจะสามารถพิมพ์ไปเรื่อย ๆ ได้ โดยไม่ต้องคอยกด Shift เพื่อทำเป็นตัวใหญ่เลย</p>
<p>สะดวกและสบายแบบนี้&#8230; เจ๋งเนอะ <img src='http://blog.chonla.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>ใครนึกภาพไม่ออก ลองไปดู <a title="LIVE DEMO - Capitalize" href="http://sandbox.chonla.com/capitalize" target="_blank">LIVE DEMO</a> ที่ <a title="LIVE DEMO - Capitalize" href="http://sandbox.chonla.com/capitalize" target="_blank">http://sandbox.chonla.com/capitalize</a> ได้ครับ</p>
<p>ท้ายสุดนี้สวัสดีปีใหม่ 2555 ครับ</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%2F12%2F%25e0%25b8%259e%25e0%25b8%25b4%25e0%25b8%25a1%25e0%25b8%259e%25e0%25b9%258c%25e0%25b9%2584%25e0%25b8%259b%25e0%25b8%2597%25e0%25b8%25b3%25e0%25b8%2595%25e0%25b8%25b1%25e0%25b8%25a7%25e0%25b9%2583%25e0%25b8%25ab%25e0%25b8%258d%25e0%25b9%2588%25e0%25b9%2584%25e0%25b8%259b%25e0%25b9%2584%25e0%25b8%25a1%25e0%25b9%2588%25e0%25b8%25a2%2F&amp;title=%E0%B8%9E%E0%B8%B4%E0%B8%A1%E0%B8%9E%E0%B9%8C%E0%B9%84%E0%B8%9B%E0%B8%97%E0%B8%B3%E0%B8%95%E0%B8%B1%E0%B8%A7%E0%B9%83%E0%B8%AB%E0%B8%8D%E0%B9%88%E0%B9%84%E0%B8%9B%E0%B9%84%E0%B8%A1%E0%B9%88%E0%B8%A2%E0%B8%B2%E0%B8%81%E0%B8%AD%E0%B8%A2%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B8%97%E0%B8%B5%E0%B9%88%E0%B8%84%E0%B8%B4%E0%B8%94" 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/12/%e0%b8%9e%e0%b8%b4%e0%b8%a1%e0%b8%9e%e0%b9%8c%e0%b9%84%e0%b8%9b%e0%b8%97%e0%b8%b3%e0%b8%95%e0%b8%b1%e0%b8%a7%e0%b9%83%e0%b8%ab%e0%b8%8d%e0%b9%88%e0%b9%84%e0%b8%9b%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b8%a2/feed/</wfw:commentRss>
		<slash:comments>0</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_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/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>Transaction ใน Database นั้นสำคัญไฉน</title>
		<link>http://blog.chonla.com/2011/07/transaction-%e0%b9%83%e0%b8%99-database-%e0%b8%99%e0%b8%b1%e0%b9%89%e0%b8%99%e0%b8%aa%e0%b8%b3%e0%b8%84%e0%b8%b1%e0%b8%8d%e0%b9%84%e0%b8%89%e0%b8%99/</link>
		<comments>http://blog.chonla.com/2011/07/transaction-%e0%b9%83%e0%b8%99-database-%e0%b8%99%e0%b8%b1%e0%b9%89%e0%b8%99%e0%b8%aa%e0%b8%b3%e0%b8%84%e0%b8%b1%e0%b8%8d%e0%b9%84%e0%b8%89%e0%b8%99/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 18:41:28 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ACID]]></category>
		<category><![CDATA[Transaction]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=332</guid>
		<description><![CDATA[โพสนี้ว่าด้วยเรื่องทฤษฎีเกี่ยวกับ transaction ใน database ล้วน ๆ พร้อมตัวอย่างประกอบให้เห็นนิดหน่อยครับ สืบเนื่องจากโพสก่อนหน้านี้ผมพูดถึง database engine ใน MySQL ไป โดยอธิบายไปว่า บางชนิดจะสนับสนุน transaction แต่บางชนิดไม่สนับสนุน แถมยังเอาลิงก์เกี่ยวกับ transaction ทิ้งไว้ให้ไปอ่านเองอีกด้วย โพสนี้เลยจะขออนุญาตมาขยายความเรื่องเกี่ยวกับ transaction ให้เห็นภาพชัดเจนมากขึ้นกันดีกว่า Transaction (ทรานแซคชั่น) หมายถึงการดำเนินการธุรกรรมอะไรซักอย่าง แล้วแต่เนื้อหาที่นำไปใช้ เช่น ไปธนาคารถอนเงิน 1 ครั้ง ก็เรียกได้ว่าเกิด 1 transaction หรือโอนเงินให้เพื่อน 1 ครั้ง ก็เรียกว่า 1 transaction ได้เช่นกัน แล้วความสำคัญของ transaction มันอยู่ตรงไหน?&#8230; ลองพิจารณากระบวนการโอนเงินดูครับ (ตัวอย่างคลาสสิคมาก) ผมโอนเงินจากบัญชี A ไปบัญชี B กระบวนการย่อยที่เกิดขึ้นคือ ถอนเงินจาก A และฝากเข้าไปที่ B [...]]]></description>
			<content:encoded><![CDATA[<p>โพสนี้ว่าด้วยเรื่องทฤษฎีเกี่ยวกับ transaction ใน database ล้วน ๆ พร้อมตัวอย่างประกอบให้เห็นนิดหน่อยครับ</p>
<p>สืบเนื่องจากโพสก่อนหน้านี้ผมพูดถึง database engine ใน MySQL ไป โดยอธิบายไปว่า บางชนิดจะสนับสนุน transaction แต่บางชนิดไม่สนับสนุน แถมยังเอาลิงก์เกี่ยวกับ transaction ทิ้งไว้ให้ไปอ่านเองอีกด้วย โพสนี้เลยจะขออนุญาตมาขยายความเรื่องเกี่ยวกับ transaction ให้เห็นภาพชัดเจนมากขึ้นกันดีกว่า</p>
<p><span id="more-332"></span>Transaction (ทรานแซคชั่น) หมายถึงการดำเนินการธุรกรรมอะไรซักอย่าง แล้วแต่เนื้อหาที่นำไปใช้ เช่น ไปธนาคารถอนเงิน 1 ครั้ง ก็เรียกได้ว่าเกิด 1 transaction หรือโอนเงินให้เพื่อน 1 ครั้ง ก็เรียกว่า 1 transaction ได้เช่นกัน แล้วความสำคัญของ transaction มันอยู่ตรงไหน?&#8230; ลองพิจารณากระบวนการโอนเงินดูครับ (ตัวอย่างคลาสสิคมาก) ผมโอนเงินจากบัญชี A ไปบัญชี B กระบวนการย่อยที่เกิดขึ้นคือ ถอนเงินจาก A และฝากเข้าไปที่ B ดังนั้นเราจะเห็นได้ว่า ในธุรกรรมการโอนเงิน 1 transaction จะมี 2 operation ย่อยเกิดขึ้นคือ ถอนเงิน และฝากเงิน</p>
<p>ปัญหาคือ ในกรณีที่ระบบล่มระหว่าง transaction ยังไม่เสร็จสิ้นล่ะ (จากตัวอย่าง เช่น ถอนเงินจาก A มาแล้ว แต่ยังไม่ได้ฝากเข้าไปที่ B) จะเกิดอะไรขึ้น&#8230; งานงอกไงครับ</p>
<p>ดังนั้น ไอ้เจ้า transaction เนี่ย อย่างน้อยจำเป็นต้องมีคุณสมบัติที่จะทำให้เรามั่นใจได้ว่า กระบวนการย่อย ๆ ที่เกิดใน transaction เนี่ย ทำงานได้อย่างสมบูรณ์นะ คุณสมบัติพวกนี้ถ้าเอาเฉพาะตัวอักษรตัวแรกของชื่อภาษาอังกฤษมาเรียงกัน จะเขียนได้เป็น ACID ดังนั้น คุณสมบัติของ transaction นี้ก็จะเรียกง่าย ๆ กันว่า ACID properties ของ transaction นั่นเอง โดยที่ ACID properties นี้จะประกอบด้วย</p>
<blockquote><p><span style="color: #808080;">ก่อนที่จะทำความรู้จัก ACID properties &#8230; ผมขอแนะนำให้รู้จักคำ 2 คำที่ใช้กันใน transaction ก่อน คือ rollback และ commit &#8230; การ <em><strong>rollback</strong></em> หมายถึงการยกเลิกสิ่งที่ทำมาทั้งหมดใน transaction นั้น ๆ ส่วนการ <em><strong>commit</strong></em> คือการยอมรับและบันทึกค่าที่เปลี่ยนแปลงทั้งหมดใน transaction นั้น ๆ</span></p></blockquote>
<p>1. Atomicity &#8211; คุณสมบัตินี้จะสอดคล้องกับตัวอย่างที่ผมพูดไปก่อนหน้านี้ โดยจะมีหลักง่าย ๆ ที่ชัดเจนคือ transaction ที่ถูกกระทำนี้มี operation ย่อย ๆ หลายคำสั่ง ถ้าทำได้ ก็หมายถึงทำได้ทั้งหมด ถ้าทำอันใดอันหนึ่งไม่ได้ จะหมายถึงทำไม่ได้เลยตั้งแต่คำสั่งแรก (All or nothing)</p>
<p>2. Consistency &#8211; คุณสมบัตินี้หมายถึงว่า ความสอดคล้องของข้อมูลจะต้องถูกต้องเสมอ ถ้าไม่ถูกต้องระบบจะต้องทำการ rollback กลับไปยังจุดที่ข้อมูลทั้งหมดสอดคล้องกันอยู่ ยกตัวอย่างเช่น จำนวนเงินที่ก่อนที่จะทำการโอนของทั้ง 2 บัญชีรวมกันจะต้องเท่ากันกับหลักจากทำการโอนแล้ว หรือข้อมูลที่เก็บเฉพาะ integer แต่เราใส่ข้อมูลที่เป็นทศนิยมเข้าไป ข้อมูลทั้งเรคอร์ดนี้ก็ไม่ควรถูกบันทึก หรือในระบบฐานข้อมูลที่มีการกำหนดฟิลด์อ้างอิงได้ (ว่าฟิลด์นี้อ้างถึงฟิลด์ไหนในตารางอื่น) การลบเรคอร์ดที่มีฟิลด์ที่ถูกอ้างอิงก็ควรจะก่อให้เกิด &#8230;</p>
<ul>
<li>ยกเลิก transaction และ rollback กลับไปยังจุดที่สอดคล้องล่าสุด&#8230;หรือ</li>
<li>ลบเรคอร์ดที่มีการอ้างถึงข้อมูลนี้&#8230;หรือ</li>
<li>ทำฟิลด์ที่อ้างถึงข้อมูลนี้ให้เป็น NULL ซะ</li>
</ul>
<p>3. Isolation &#8211; หมายถึงว่า การประมวลผล transaction หนึ่ง ๆ ถ้ามันยังไม่เสร็จ transaction อื่น ๆ จะต้องไม่เห็นผลจากการกระทำของ transaction นี้ เช่น transaction ที่ 1 โอนเงินจากบัญชี A ไป B จำนวน 200 บาท และ transaction ที่ 2 คือ ถอนเงินจาก A 100 บาท กำหนดให้ในขั้นตอนของ transaction ที่ 2 เกิดขึ้นหลังจากที่ถอนเงินออกจาก A ไป 200 เพื่อที่จะนำไปฝากเข้า B แล้ว จากคุณสมบัติของ Isolation นี้จะทำให้ transaction ที่ 2 ยังไม่เห็นว่า A เงินหายไปแล้ว 200 หรือ B ได้รับเงินแล้ว 200</p>
<p>4. Durability &#8211; หมายถึง transaction ใด ๆ ก็ตามที่ทำการ commit แล้ว ข้อมูลจะต้องอยู่แบบนั้น ไม่ว่าระบบจะล่มยังไง เมื่อกู้คืนมาได้ transaction นั้นก็จะยังถือว่า commit และประมวลผลเสร็จสิ้นแล้ว</p>
<p>ครบ 4 อย่างแล้ว&#8230; พอเห็นภาพความสำคัญของ transaction ใน database มากขึ้นแล้วหรือยังครับ</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%2F07%2Ftransaction-%25e0%25b9%2583%25e0%25b8%2599-database-%25e0%25b8%2599%25e0%25b8%25b1%25e0%25b9%2589%25e0%25b8%2599%25e0%25b8%25aa%25e0%25b8%25b3%25e0%25b8%2584%25e0%25b8%25b1%25e0%25b8%258d%25e0%25b9%2584%25e0%25b8%2589%25e0%25b8%2599%2F&amp;title=Transaction%20%E0%B9%83%E0%B8%99%20Database%20%E0%B8%99%E0%B8%B1%E0%B9%89%E0%B8%99%E0%B8%AA%E0%B8%B3%E0%B8%84%E0%B8%B1%E0%B8%8D%E0%B9%84%E0%B8%89%E0%B8%99" 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/2011/07/transaction-%e0%b9%83%e0%b8%99-database-%e0%b8%99%e0%b8%b1%e0%b9%89%e0%b8%99%e0%b8%aa%e0%b8%b3%e0%b8%84%e0%b8%b1%e0%b8%8d%e0%b9%84%e0%b8%89%e0%b8%99/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ทำความรู้จักกับ Storage Engine ของ MySQL กันหน่อย</title>
		<link>http://blog.chonla.com/2011/07/%e0%b8%97%e0%b8%b3%e0%b8%84%e0%b8%a7%e0%b8%b2%e0%b8%a1%e0%b8%a3%e0%b8%b9%e0%b9%89%e0%b8%88%e0%b8%b1%e0%b8%81%e0%b8%81%e0%b8%b1%e0%b8%9a-storage-engine-%e0%b8%82%e0%b8%ad%e0%b8%87-mysql-%e0%b8%81/</link>
		<comments>http://blog.chonla.com/2011/07/%e0%b8%97%e0%b8%b3%e0%b8%84%e0%b8%a7%e0%b8%b2%e0%b8%a1%e0%b8%a3%e0%b8%b9%e0%b9%89%e0%b8%88%e0%b8%b1%e0%b8%81%e0%b8%81%e0%b8%b1%e0%b8%9a-storage-engine-%e0%b8%82%e0%b8%ad%e0%b8%87-mysql-%e0%b8%81/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 16:01:11 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Database Engines]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=327</guid>
		<description><![CDATA[MySQL พูดชื่อนี้ ผมว่า developer หลาย ๆ คน ก็คงต้องรู้จักฐานข้อมูลยอดนิยมตัวนี้ แต่จะมีใครรู้บ้างว่า MySQL เนี่ย มันมี storage engine ให้เลือกใช้หลายแบบนะ แล้วแบบไหนที่เหมาะกับงานของเราล่ะ? (ใครไม่รู้จักว่า storage engine นั้นหมายถึงอะไร database engine เรียกง่าย ๆ ก็เหมือนชนิดของฐานข้อมูล สาเหตุที่เราต้องเลือกชนิด engine ให้เหมาะสมนั้น เปรียบเทียบง่าย ๆ ว่า มันก็เหมือนกับเสื้อผ้า เสื้อผ้ามีหลายประเภท เราใส่ออกไปนอกบ้านได้ทุกแบบ แต่แบบไหนที่เหมาะกับกาลเทศะ และงานที่ทำ อย่างเช่น ชุดกันไฟกับงานนักดับเพลิง จะให้ใส่สูทไปดับไฟก็ได้ แต่มันไม่ถนัด&#8230;) การที่เราจะรู้ว่า storage engine แบบไหนเหมาะกับเรานั้น เราก็ต้องมาทำความรู้จักกับ storage engine แต่ละชนิดกันก่อน เพื่อไม่ให้เป็นการเสียเวลา เรามาทำความรู้จักกับ storage engine แต่ละตัวกันดีกว่า (เราสามารถกำหนดให้แต่ละตารางใช้ engine ต่างกันได้ตามความเหมาะสมในการใช้งาน) ISAM เป็น storage engine ที่ถูกออกแบบมาโดยที่มีแนวคิดที่ว่า ตารางมักจะถูกอ่านมากกว่าอัพเดท [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL พูดชื่อนี้ ผมว่า developer หลาย ๆ คน ก็คงต้องรู้จักฐานข้อมูลยอดนิยมตัวนี้ แต่จะมีใครรู้บ้างว่า MySQL เนี่ย มันมี storage engine ให้เลือกใช้หลายแบบนะ แล้วแบบไหนที่เหมาะกับงานของเราล่ะ? (ใครไม่รู้จักว่า storage engine นั้นหมายถึงอะไร database engine เรียกง่าย ๆ ก็เหมือนชนิดของฐานข้อมูล สาเหตุที่เราต้องเลือกชนิด engine ให้เหมาะสมนั้น เปรียบเทียบง่าย ๆ ว่า มันก็เหมือนกับเสื้อผ้า เสื้อผ้ามีหลายประเภท เราใส่ออกไปนอกบ้านได้ทุกแบบ แต่แบบไหนที่เหมาะกับกาลเทศะ และงานที่ทำ อย่างเช่น ชุดกันไฟกับงานนักดับเพลิง จะให้ใส่สูทไปดับไฟก็ได้ แต่มันไม่ถนัด&#8230;)</p>
<p>การที่เราจะรู้ว่า storage engine แบบไหนเหมาะกับเรานั้น เราก็ต้องมาทำความรู้จักกับ storage engine แต่ละชนิดกันก่อน เพื่อไม่ให้เป็นการเสียเวลา เรามาทำความรู้จักกับ storage engine แต่ละตัวกันดีกว่า (เราสามารถกำหนดให้แต่ละตารางใช้ engine ต่างกันได้ตามความเหมาะสมในการใช้งาน)</p>
<p><span id="more-327"></span></p>
<ul>
<li>ISAM เป็น storage engine ที่ถูกออกแบบมาโดยที่มีแนวคิดที่ว่า ตารางมักจะถูกอ่านมากกว่าอัพเดท ทำให้ storage engine ชนิดนี้สามารถประมวลผลคำสั่งที่เป็นการอ่านได้อย่างรวดเร็วมาก ๆ แต่มีข้อเสียใหญ่ ๆ คือการไม่สนับสนุนการทำงานแบบ transaction (คือไม่สามารถ rollback ได้ ถ้าเกิดกรณีการทำงานไม่สมบูรณ์ ทางทฤษฎีเรียกว่า ACID transaction properties : สามารถอ่านเพิ่มเติมได้จากที่ <a href="http://en.wikipedia.org/wiki/ACID">http://en.wikipedia.org/wiki/ACID</a>)  และไม่รองรับระบบ fault-tolerant (คือถ้าระบบล่ม ก็อาจจะไม่สามารถที่จะกู้ข้อมูลกลับขึ้นมาได้เลย) ดังนั้นถ้าจะใช้ engine นี้ในงานสำคัญ ก็แนะนำว่าหมั่น backup บ่อย ๆ ครับ</li>
<li>MyISAM เป็น engine ยอดนิยมสำหรับเว็บทั่ว ๆ ไป พัฒนาต่อเนื่องมาจาก ISAM ทำให้ความเร็วในการอ่านยังเป็นเรื่องที่โดดเด่นอยู่เหมือนเดิม นอกจากนี้แล้วยังมีการเพิ่มส่วนของการทำ indexing และ operation สำหรับ field บางอย่างลงไปด้วย ข้อดีอีกอย่างคือ ใน MyISAM นี้ มี tool ที่ใช้ในการกู้ข้อมูลในกรณีที่ตารางมีปัญหาด้วย (MyISAMChk) แต่ข้อเสียที่สำคัญก็ยังคงอยู่คือ ไม่สนับสนุนการทำงานแบบ transaction และคำสั่ง update ยังส่งผลให้เกิดขยะที่ไม่จำเป็นอีกด้วย ทำให้เราต้องใช้คำสั่ง OPTIMIZE เพื่อจัดการขยะพวกนี้ให้หายไปจากตาราง</li>
<li>HEAP (หรือ Memory) เป็น engine ที่ไม่ได้สร้างตารางขึ้นมาเป็นไฟล์จริง ๆ เหมือนกับ engine อื่น ๆ แต่จะสร้างตารางลงใน Memory ของเครื่อง ทำให้การเข้าถึงทำได้รวดเร็วยิ่งกว่า ISAM และ MyISAM แต่ข้อเสียคือ มันไม่อยู่ถาวร ถ้ามีการปิดเครื่องหรือระบบล่มโดยที่ยังไม่ได้บันทึกค่าในตารางลงไฟล์ ข้อมูลใน Memory ขณะนั้นก็จะหายไปทั้งหมด ไม่สามารถกู้คืนได้ และทุกครั้งที่ใช้งานตารางที่ใช้ engine นี้เสร็จ ก็จะต้องลบตารางนี้ทิ้งด้วย ไม่เช่นนั้นแล้วจะเกิดขยะใน Memory อาจจะทำให้ Memory ไม่พอในการทำงานได้</li>
<li>InnoDB และ Berkley DB (BDB) เป็นฐานข้อมูลที่ถูกพัฒนามาให้สนับสนุน transaction และแถมด้วยการสนับสนุน Foreign Key แต่ก็มีข้อเสียคือมันช้ากว่า ISAM และ MyISAM แต่สำหรับผู้ที่จำเป็นจะต้องใช้ transaction แล้ว ก็คงเลี่ยงไม่ได้ที่จะใช้ engine ชนิดนี้</li>
<li>Cluster ถูกพัฒนาขึ้นเพื่อเพิ่ม High Availability และ High Performance (ประมาณว่าใช้งานได้นาน ๆ และมีประสิทธิภาพดี) แต่ก็จะต้องใช้ resource ในการ implement ค่อนข้างมากเช่นเดียวกัน โดยที่ engine สำหรับ Cluster นี้มีชื่อว่า NDB หรือ NDBCLUSTER (NDB = Network Database)</li>
</ul>
<div>(จริง ๆ แล้วมี storage engine อีกมากมายที่ถูกพัฒนาขึ้นมาใช้กับ MySQL แต่ผมขอไม่พูดถึง เพราะมันเยอะมาก และเราก็ไม่ค่อยได้ใช้งานเท่าไรนัก ผู้ที่สนใจ เข้าไปดูรายละเอียดได้ที่ <a href="http://en.wikipedia.org/wiki/MySQL">http://en.wikipedia.org/wiki/MySQL</a>)</div>
<div>ถึงตอนนี้ ผมว่าเราคงสามารถที่จัดตัดสินใจได้ง่ายขึ้นแล้วว่าจะใช้ engine แบบไหนกับตารางของเราดี</div>
<div>อ้างอิง</div>
<div>
<ul>
<li><a href="http://www.techrepublic.com/article/a-fast-and-furious-guide-to-mysql-database-engines/1058872">http://www.techrepublic.com/article/a-fast-and-furious-guide-to-mysql-database-engines/1058872</a></li>
<li><a href="http://en.wikipedia.org/wiki/MySQL">http://en.wikipedia.org/wiki/MySQL</a></li>
<li><a href="http://en.wikipedia.org/wiki/MySQL_Cluster">http://en.wikipedia.org/wiki/MySQL_Cluster</a></li>
</ul>
</div>
<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%2F07%2F%25e0%25b8%2597%25e0%25b8%25b3%25e0%25b8%2584%25e0%25b8%25a7%25e0%25b8%25b2%25e0%25b8%25a1%25e0%25b8%25a3%25e0%25b8%25b9%25e0%25b9%2589%25e0%25b8%2588%25e0%25b8%25b1%25e0%25b8%2581%25e0%25b8%2581%25e0%25b8%25b1%25e0%25b8%259a-storage-engine-%25e0%25b8%2582%25e0%25b8%25ad%25e0%25b8%2587-mysql-%25e0%25b8%2581%2F&amp;title=%E0%B8%97%E0%B8%B3%E0%B8%84%E0%B8%A7%E0%B8%B2%E0%B8%A1%E0%B8%A3%E0%B8%B9%E0%B9%89%E0%B8%88%E0%B8%B1%E0%B8%81%E0%B8%81%E0%B8%B1%E0%B8%9A%20Storage%20Engine%20%E0%B8%82%E0%B8%AD%E0%B8%87%20MySQL%20%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%A2" 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/2011/07/%e0%b8%97%e0%b8%b3%e0%b8%84%e0%b8%a7%e0%b8%b2%e0%b8%a1%e0%b8%a3%e0%b8%b9%e0%b9%89%e0%b8%88%e0%b8%b1%e0%b8%81%e0%b8%81%e0%b8%b1%e0%b8%9a-storage-engine-%e0%b8%82%e0%b8%ad%e0%b8%87-mysql-%e0%b8%81/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sync ข้อมูลจำนวนนับจากตารางอื่นด้วย subquery</title>
		<link>http://blog.chonla.com/2011/06/sync-%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%88%e0%b8%b3%e0%b8%99%e0%b8%a7%e0%b8%99%e0%b8%99%e0%b8%b1%e0%b8%9a%e0%b8%88%e0%b8%b2%e0%b8%81%e0%b8%95%e0%b8%b2%e0%b8%a3%e0%b8%b2/</link>
		<comments>http://blog.chonla.com/2011/06/sync-%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%88%e0%b8%b3%e0%b8%99%e0%b8%a7%e0%b8%99%e0%b8%99%e0%b8%b1%e0%b8%9a%e0%b8%88%e0%b8%b2%e0%b8%81%e0%b8%95%e0%b8%b2%e0%b8%a3%e0%b8%b2/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 18:42:40 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[Subquery]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=324</guid>
		<description><![CDATA[ถ้าว่าตามทฤษฎีฐานข้อมูลแล้วนั้น การ Normalization ตารางเพื่อลดความซ้ำซ้อนของข้อมูล (Redundancy) เป็นสิ่งที่จำเป็นมาก แต่ในการใช้งานจริง การ Normalization ที่มากเกินไป อาจจะก่อผลเสียได้ ยกตัวอย่างเช่น หน้าแสดงกระทู้ในเว็บบอร์ด X จะแสดงข้อมูลจำนวน comment ที่สมาชิกเข้ามาตอบในหัวข้อนั้น ๆ ถ้าเราทำ Normalization ตารางของเว็บบอร์ดตามทฤษฎี โดยให้ตารางที่เก็บความคิดเห็น (comment) แยกจากกระทู้ (topic) ในตาราง comment มี Foreign Key ชื่อว่า topic_id ที่เชื่อมอยู่กับ Primary Key ที่ชื่อ id ในตาราง topic เราจะเห็นได้ว่าข้อมูลจำนวนของ comment เราสามารถที่จะทำ subquery ออกมาแสดงผลได้ ยกตัวอย่าง (แบบไม่คิดอะไรมาก) เช่น SELECT *, (SELECT count( * ) FROM comment [...]]]></description>
			<content:encoded><![CDATA[<p>ถ้าว่าตามทฤษฎีฐานข้อมูลแล้วนั้น การ Normalization ตารางเพื่อลดความซ้ำซ้อนของข้อมูล (Redundancy) เป็นสิ่งที่จำเป็นมาก แต่ในการใช้งานจริง การ Normalization ที่มากเกินไป อาจจะก่อผลเสียได้ ยกตัวอย่างเช่น หน้าแสดงกระทู้ในเว็บบอร์ด X จะแสดงข้อมูลจำนวน comment ที่สมาชิกเข้ามาตอบในหัวข้อนั้น ๆ ถ้าเราทำ Normalization ตารางของเว็บบอร์ดตามทฤษฎี โดยให้ตารางที่เก็บความคิดเห็น (comment) แยกจากกระทู้ (topic) ในตาราง comment มี Foreign Key ชื่อว่า topic_id ที่เชื่อมอยู่กับ Primary Key ที่ชื่อ id ในตาราง topic เราจะเห็นได้ว่าข้อมูลจำนวนของ comment เราสามารถที่จะทำ subquery ออกมาแสดงผลได้ ยกตัวอย่าง (แบบไม่คิดอะไรมาก) เช่น</p>
<pre name="code" class="sql">
SELECT  *, (</code>SELECT count(  *  ) FROM comment WHERE topic_id = t.id) rcount FROM  `topic` t
</pre>
<p><span id="more-324"></span>ทีนี้ข้อเสียมันอยู่ตรงไหน? ถ้ายังไม่เห็น ลองสังเกตดี ๆ อีกทีครับ ใครยังนึกไม่ออก ผมจะยกตัวอย่างที่ทำให้เห็นชัดเจนมากขึ้น สมมติว่า แต่ละกระทู้ มีคนตอบกระทู้โดยเฉลี่ยกระทู้ละ 50 comment คำสั่ง COUNT มันก็จะไปนั่งนับจนครบ 50 comment โดย filter ตาม t.id ที่กำหนดแต่ถ้ามีมากกว่านี้ล่ะ เว็บไซต์ดัง ๆ ฮอต ๆ สมาชิกล้นหลาม คนตอบกระทู้เป็นร้อย ๆ พัน ๆ ล่ะ</p>
<p>จะเห็นได้ว่า &#8220;ทุกครั้ง&#8221; ที่มีคนเปิดหน้าแสดงรายชื่อกระทู้ มันจะต้องไปนั่งนับทุกครั้ง ทั้ง ๆ ที่อาจจะไม่ได้มีใครไปตอบกระทู้เพิ่มเลยก็ได้ สิ่งที่เราได้กลับมาจากการทำ Normalization ในครั้งนี้คือ การสิ้นเปลือง CPU สุด ๆ นั่นเอง เรามาหาทางแก้ปัญหากันดีกว่า</p>
<p>วิธีแก้ปัญหาแบบหนึ่งที่ผมจะพูดถึงในครั้งนี้คือการทำ cache ผมไม่ได้หมายถึงการทำ file cache หรือ memory cache นะ แต่ผมหมายถึงการ cache ลงไปในฟิลด์ในตารางครับ</p>
<p>พูดให้ชัดเจนอีกนิดคือ ผมหมายถึงการเพิ่มความซ้ำซ้อนของข้อมูลลงไปอีกนิด เพื่อชีวิตที่ดีกว่า โดยการเพิ่มฟิลด์ชื่อ comment_count ลงไปในตาราง topic และทุกครั้งที่มีการตอบกระทู้ หรือลบ comment ผมก็แค่มาอัพเดทฟิลด์นี้ด้วยเท่านั้นเอง</p>
<pre name="code" class="sql">
UPDATE topic SET comment_count = (SELECT COUNT(*) comment_count FROM comment WHERE topic_id = t.id)
</pre>
<p>ด้วย SQL Statement ข้างบนนี้ มันก็จะไป sync ข้อมูลจำนวนนับจากตาราง comment มาลงในตาราง topic ให้ผม และทุกครั้งที่แสดงหน้ากระทู้ ผมก็เอา comment_count ไปใช้แทน subquery ได้เลย สบายจริง ๆ ครับ</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%2F06%2Fsync-%25e0%25b8%2582%25e0%25b9%2589%25e0%25b8%25ad%25e0%25b8%25a1%25e0%25b8%25b9%25e0%25b8%25a5%25e0%25b8%2588%25e0%25b8%25b3%25e0%25b8%2599%25e0%25b8%25a7%25e0%25b8%2599%25e0%25b8%2599%25e0%25b8%25b1%25e0%25b8%259a%25e0%25b8%2588%25e0%25b8%25b2%25e0%25b8%2581%25e0%25b8%2595%25e0%25b8%25b2%25e0%25b8%25a3%25e0%25b8%25b2%2F&amp;title=Sync%20%E0%B8%82%E0%B9%89%E0%B8%AD%E0%B8%A1%E0%B8%B9%E0%B8%A5%E0%B8%88%E0%B8%B3%E0%B8%99%E0%B8%A7%E0%B8%99%E0%B8%99%E0%B8%B1%E0%B8%9A%E0%B8%88%E0%B8%B2%E0%B8%81%E0%B8%95%E0%B8%B2%E0%B8%A3%E0%B8%B2%E0%B8%87%E0%B8%AD%E0%B8%B7%E0%B9%88%E0%B8%99%E0%B8%94%E0%B9%89%E0%B8%A7%E0%B8%A2%20subquery" 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/2011/06/sync-%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%88%e0%b8%b3%e0%b8%99%e0%b8%a7%e0%b8%99%e0%b8%99%e0%b8%b1%e0%b8%9a%e0%b8%88%e0%b8%b2%e0%b8%81%e0%b8%95%e0%b8%b2%e0%b8%a3%e0%b8%b2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>สร้าง dynamic object แบบ runtime</title>
		<link>http://blog.chonla.com/2011/05/%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2%e0%b8%87-dynamic-object-%e0%b9%81%e0%b8%9a%e0%b8%9a-runtime/</link>
		<comments>http://blog.chonla.com/2011/05/%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2%e0%b8%87-dynamic-object-%e0%b9%81%e0%b8%9a%e0%b8%9a-runtime/#comments</comments>
		<pubDate>Mon, 23 May 2011 17:58:17 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[instantiate]]></category>
		<category><![CDATA[Run-Time]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=319</guid>
		<description><![CDATA[จริง ๆ ใน php วิธีการสร้าง object นั้น สำหรับคนที่เคยเขียน class มาแล้ว มันไม่ใช่เรื่องยากอะไรเลย แค่ใช้ keyword ว่า new เท่านั้นเองครับ เรื่องที่ผมจะคุยต่อจากนี้ เป็นเรื่องที่ไม่ได้ใหม่เลย แต่เป็นการนำสิ่งที่รู้อยู่แล้วมาประยุกต์ใช้ร่วมกันในกรอบที่หลาย ๆ คนอาจจะรู้จักดีอยู่แล้ว&#8230; Factory นั่นเองครับ Factory pattern เป็นรูปแบบที่ทำให้เราสามารถสร้าง object (instantiate) ได้ในช่วง runtime โดยการส่ง parameter ที่เป็นชื่อ class name เข้าไปเท่านั้น ไอเดียตรงนี้ ใครเคยเขียนโค๊ดใน Joomla อาจจะเคยเห็นชื่อ JFactory กันมาบ้าง จากเดิมที่เราเคยเขียนโค๊ดเพื่อที่จะเลือกสร้าง object ประมาณนี้ include_once ('class/object.class.php'); $obj = new ClassName(); $obj-&#62;display(); หรือ จะเป็นแบบที่ dynamic [...]]]></description>
			<content:encoded><![CDATA[<p>จริง ๆ ใน php วิธีการสร้าง object นั้น สำหรับคนที่เคยเขียน class มาแล้ว มันไม่ใช่เรื่องยากอะไรเลย แค่ใช้ keyword ว่า new เท่านั้นเองครับ เรื่องที่ผมจะคุยต่อจากนี้ เป็นเรื่องที่ไม่ได้ใหม่เลย แต่เป็นการนำสิ่งที่รู้อยู่แล้วมาประยุกต์ใช้ร่วมกันในกรอบที่หลาย ๆ คนอาจจะรู้จักดีอยู่แล้ว&#8230; Factory นั่นเองครับ</p>
<p><span id="more-319"></span>Factory pattern เป็นรูปแบบที่ทำให้เราสามารถสร้าง object (instantiate) ได้ในช่วง runtime โดยการส่ง parameter ที่เป็นชื่อ class name เข้าไปเท่านั้น ไอเดียตรงนี้ ใครเคยเขียนโค๊ดใน Joomla อาจจะเคยเห็นชื่อ JFactory กันมาบ้าง</p>
<p>จากเดิมที่เราเคยเขียนโค๊ดเพื่อที่จะเลือกสร้าง object ประมาณนี้</p>
<pre class="js">include_once ('class/object.class.php');
$obj = new ClassName();
$obj-&gt;display();</pre>
<p>หรือ จะเป็นแบบที่ dynamic ขึ้นกว่าเดิมอีกนิดนึง</p>
<pre class="js">$obj = null;
if ($action == 'check') {
include_once ('class/check.class.php');
$obj = new ClassCheck();
} elseif ($action == 'dispatch') {
include_once ('class/dispatch.class.php');
$obj = new ClassDispatch();
} else {
include_once ('class/default.class.php');
$obj = new ClassDefault();
}
$obj-&gt;execute();</pre>
<p>จะเห็นว่าแบบที่ 2 จะ dynamic กว่าแบบ 1 แต่ยาวเหยียด เราจะรวบรัดแก้ไขปัญหาเรื่องนี้โดยการใช้ Factory Pattern โดยการสร้าง class ขึ้นมา 1 class และมี static function 1 ตัว ชื่อ create (จริง ๆ จะใช้ชื่ออื่นก็ได้) ยกตัวอย่างเช่น</p>
<pre class="js">class XFactory {
public static function create($classname) {
if (include_once 'classpath/'.$classname) {
$clsn = 'Class' . ucfirst($classname);
if (class_exists($clsn)) {
return new $clsn;
} else {
throw new Exception('Class not found');
}
} else {
throw new Exception('Class not found');
}
}
}</pre>
<p>ทีนี้เวลาเราจะใช้งานก็เรียกใช้แค่นี้ครับ</p>
<pre class="js">$chkobj = XFactory::create('check');
$dspobj = XFactory::create('dispatch');</pre>
<p>คราวนี้ง่ายขึ้นมั๊ยครับ <img src='http://blog.chonla.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>อ้างอิง</p>
<ul>
<li><span style="color: #0000ee;"><a href="http://php.net/manual/en/language.oop5.patterns.php">http://php.net/manual/en/language.oop5.patterns.php</a></span></li>
<li><a href="http://truelogic.org/wordpress/2011/03/27/a-very-efficient-way-of-instantiating-a-class-dynamically-in-php/">http://truelogic.org/wordpress/2011/03/27/a-very-efficient-way-of-instantiating-a-class-dynamically-in-php/</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%2F2011%2F05%2F%25e0%25b8%25aa%25e0%25b8%25a3%25e0%25b9%2589%25e0%25b8%25b2%25e0%25b8%2587-dynamic-object-%25e0%25b9%2581%25e0%25b8%259a%25e0%25b8%259a-runtime%2F&amp;title=%E0%B8%AA%E0%B8%A3%E0%B9%89%E0%B8%B2%E0%B8%87%20dynamic%20object%20%E0%B9%81%E0%B8%9A%E0%B8%9A%20runtime" 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/2011/05/%e0%b8%aa%e0%b8%a3%e0%b9%89%e0%b8%b2%e0%b8%87-dynamic-object-%e0%b9%81%e0%b8%9a%e0%b8%9a-runtime/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_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/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>enable() กับ disable() ที่ขาดหายไปใน jQuery</title>
		<link>http://blog.chonla.com/2010/12/enable-%e0%b8%81%e0%b8%b1%e0%b8%9a-disable-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b8%82%e0%b8%b2%e0%b8%94%e0%b8%ab%e0%b8%b2%e0%b8%a2%e0%b9%84%e0%b8%9b%e0%b9%83%e0%b8%99-jquery/</link>
		<comments>http://blog.chonla.com/2010/12/enable-%e0%b8%81%e0%b8%b1%e0%b8%9a-disable-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b8%82%e0%b8%b2%e0%b8%94%e0%b8%ab%e0%b8%b2%e0%b8%a2%e0%b9%84%e0%b8%9b%e0%b9%83%e0%b8%99-jquery/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 17:57:26 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[disable]]></category>
		<category><![CDATA[enable]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=310</guid>
		<description><![CDATA[คนใช้ jQuery น่าจะเคยเจอปัญหาเดียวกันคือ อยากจะ disable หรือ enable ปุ่ม ด้วย jQuery แต่ติดตรงที่มันไม่มี function มาให้ ทำให้เราต้องเขียนใช้งานเองบ่อย ๆ ปกติแล้ว ถ้าใช้ไม่เยอะ ผมจะเขียนตรง ๆ ง่าย ๆ เอา โดยจะเขียนประมาณนี้ครับ $('#selector').attr('disabled','disabled'); // สำหรับ disable $('#selector').removeAttr('disabled'); // สำหรับ enable แต่ถ้าใช้บ่อย ๆ แล้ว จะให้มาเขียนแบบนี้อยู่ตลอด ก็คงจะไม่สะดวกนัก จะให้เขียนเป็น function มาครอบก็อาจจะดูไม่เก๋เท่ากับเขียนให้มันเป็น แบบ plugin ซะเลย (function($)  { $.fn.disable = function() {return this.attr('disabled', true).addClass('disabled');} $.fn.enable = function() {return this.removeClass('disabled').attr('disabled', [...]]]></description>
			<content:encoded><![CDATA[<p>คนใช้ jQuery น่าจะเคยเจอปัญหาเดียวกันคือ อยากจะ disable หรือ enable ปุ่ม ด้วย jQuery แต่ติดตรงที่มันไม่มี function มาให้ ทำให้เราต้องเขียนใช้งานเองบ่อย ๆ ปกติแล้ว ถ้าใช้ไม่เยอะ ผมจะเขียนตรง ๆ ง่าย ๆ เอา โดยจะเขียนประมาณนี้ครับ</p>
<pre class="js">$('#selector').attr('disabled','disabled'); // สำหรับ disable
$('#selector').removeAttr('disabled'); // สำหรับ enable
</pre>
<p><span id="more-310"></span>แต่ถ้าใช้บ่อย ๆ แล้ว จะให้มาเขียนแบบนี้อยู่ตลอด ก็คงจะไม่สะดวกนัก จะให้เขียนเป็น function มาครอบก็อาจจะดูไม่เก๋เท่ากับเขียนให้มันเป็น แบบ plugin ซะเลย</p>
<pre class="js">(function($)  {
$.fn.disable = function() {return this.attr('disabled', true).addClass('disabled');}
$.fn.enable = function() {return this.removeClass('disabled').attr('disabled', false);}
})(jQuery);
</pre>
<p>เท่านี้ก็เรียกใช้ .disable() กับ .enable() ได้ละ &#8230; เก๋ซะไม่มี 5555</p>
<p><a title="jQuery Plugin : Disable" href="http://sandbox.chonla.com/disable/jquery.disable.js" target="_blank">โหลด plugin ตัวนี้ที่นี่เลยครับ</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%2F2010%2F12%2Fenable-%25e0%25b8%2581%25e0%25b8%25b1%25e0%25b8%259a-disable-%25e0%25b8%2597%25e0%25b8%25b5%25e0%25b9%2588%25e0%25b8%2582%25e0%25b8%25b2%25e0%25b8%2594%25e0%25b8%25ab%25e0%25b8%25b2%25e0%25b8%25a2%25e0%25b9%2584%25e0%25b8%259b%25e0%25b9%2583%25e0%25b8%2599-jquery%2F&amp;title=enable%28%29%20%E0%B8%81%E0%B8%B1%E0%B8%9A%20disable%28%29%20%E0%B8%97%E0%B8%B5%E0%B9%88%E0%B8%82%E0%B8%B2%E0%B8%94%E0%B8%AB%E0%B8%B2%E0%B8%A2%E0%B9%84%E0%B8%9B%E0%B9%83%E0%B8%99%20jQuery" 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/2010/12/enable-%e0%b8%81%e0%b8%b1%e0%b8%9a-disable-%e0%b8%97%e0%b8%b5%e0%b9%88%e0%b8%82%e0%b8%b2%e0%b8%94%e0%b8%ab%e0%b8%b2%e0%b8%a2%e0%b9%84%e0%b8%9b%e0%b9%83%e0%b8%99-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>jQuery 1.4.4 Cheat Sheet</title>
		<link>http://blog.chonla.com/2010/11/jquery-1-4-4-cheat-sheet/</link>
		<comments>http://blog.chonla.com/2010/11/jquery-1-4-4-cheat-sheet/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 05:07:33 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Cheat Sheet]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=307</guid>
		<description><![CDATA[Cheat Sheet ในที่นี้ อธิบายให้เห็นภาพชัด ๆ ก็คงหมายถึงโพยที่ใช้แอบเอาเข้าห้องสอบครับ (ใครเคยทำมั่ง สารภาพมาซะดี ๆ) หน้าตาโพยปกติแล้วก็จะเป็นกระดาษแผ่นนึง จดมันทุกอย่างที่ต้องใช้สอบลงไป ใช่ครับ jQuery Cheat Sheet ที่ผมกำลังจะพูดถึงก็เป็นแบบนั้น jQuery 1.4.4 Cheat Sheet ก็จะเป็นโพยที่รวมเอา function ทุุกอย่างของ jQuery 1.4.4 รวมถึงมี remark เล็ก ๆ ไว้ด้วยว่าอะไรเป็นอะไร ใช้ได้กับ jQuery เวอร์ชั่นไหน ข้อดีของ Cheat Sheet คือ มันรวมทุกอย่างไว้ในหน้าเดียว ไม่ต้องเสียเวลาไปหาจากตรงไหนอีก ถ้าหน้านี้ไม่มี ก็คือไม่มีแล้วครับ เรียกได้ว่า สะดวกสุด ๆ ไปเลย บนหน้าเว็บยังมีเวอร์ชั่น pdf และ png ให้โหลดเก็บไว้ได้อีกด้วย แต่เนื่องจากมันเป็น Cheat Sheet มันเลยไม่มีรายละเอียดของ function [...]]]></description>
			<content:encoded><![CDATA[<p>Cheat Sheet ในที่นี้ อธิบายให้เห็นภาพชัด ๆ ก็คงหมายถึงโพยที่ใช้แอบเอาเข้าห้องสอบครับ (ใครเคยทำมั่ง สารภาพมาซะดี ๆ) หน้าตาโพยปกติแล้วก็จะเป็นกระดาษแผ่นนึง จดมันทุกอย่างที่ต้องใช้สอบลงไป ใช่ครับ jQuery Cheat Sheet ที่ผมกำลังจะพูดถึงก็เป็นแบบนั้น</p>
<p><span id="more-307"></span>jQuery 1.4.4 Cheat Sheet ก็จะเป็นโพยที่รวมเอา function ทุุกอย่างของ jQuery 1.4.4 รวมถึงมี remark เล็ก ๆ ไว้ด้วยว่าอะไรเป็นอะไร ใช้ได้กับ jQuery เวอร์ชั่นไหน</p>
<p>ข้อดีของ Cheat Sheet คือ มันรวมทุกอย่างไว้ในหน้าเดียว ไม่ต้องเสียเวลาไปหาจากตรงไหนอีก ถ้าหน้านี้ไม่มี ก็คือไม่มีแล้วครับ เรียกได้ว่า สะดวกสุด ๆ ไปเลย บนหน้าเว็บยังมีเวอร์ชั่น pdf และ png ให้โหลดเก็บไว้ได้อีกด้วย แต่เนื่องจากมันเป็น Cheat Sheet มันเลยไม่มีรายละเอียดของ function นั้น ๆ ว่าเอาไว้ทำอะไร ตัวอย่างการใช้งาน ก็คือ เราจะใช้ เราต้องรู้อยู่แล้วว่ามันทำอะไรครับ</p>
<p>ใครสนใจไปชมไปโหลด เชิญได้เลยที่ <a title="jQuery Cheat Sheet" href="http://jqapi.ru/" target="_blank">http://jqapi.ru/</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%2F2010%2F11%2Fjquery-1-4-4-cheat-sheet%2F&amp;title=jQuery%201.4.4%20Cheat%20Sheet" 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/2010/11/jquery-1-4-4-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

