<?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; HTTP</title>
	<atom:link href="http://blog.chonla.com/category/http/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.chonla.com</link>
	<description>คุยกันเรื่อง jQuery, Ajax, PHP, JSON, XML และ Web Technologies เป็นภาษาไทยกันดีกว่า</description>
	<lastBuildDate>Wed, 08 Sep 2010 19:28:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<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[APC]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Souce Code]]></category>
		<category><![CDATA[jQuery]]></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 addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></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>Redirect แล้วอย่าคิดว่าจะไม่เห็นนะ</title>
		<link>http://blog.chonla.com/2008/11/redirect-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7%e0%b8%ad%e0%b8%a2%e0%b9%88%e0%b8%b2%e0%b8%84%e0%b8%b4%e0%b8%94%e0%b8%a7%e0%b9%88%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%80%e0%b8%ab/</link>
		<comments>http://blog.chonla.com/2008/11/redirect-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7%e0%b8%ad%e0%b8%a2%e0%b9%88%e0%b8%b2%e0%b8%84%e0%b8%b4%e0%b8%94%e0%b8%a7%e0%b9%88%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%80%e0%b8%ab/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 13:45:19 +0000</pubDate>
		<dc:creator>chonla</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[HTTP Header]]></category>
		<category><![CDATA[Redirect]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.chonla.com/?p=132</guid>
		<description><![CDATA[คำสั่งการทำ Redirect ใน PHP นั้น อย่างที่เรารู้ ๆ กันอยู่ว่าเพียงแค่พิมพ์ว่า header("location:http://blog.chonla.com"); ซึ่งความจริงแล้ว มันเป็นการกำหนดค่า Location ลงไปใน HTTP Header นั่นเอง เรายังสามารถกำหนด Header อื่น ๆ ลงไปใน HTTP Header ได้อีก แต่วันนี้ผมจะพูดถึงเฉพาะ Location ครับ มีหลายคนหลงคิดไปเองว่า การสั่ง Redirect ด้วยวิธีนี้นั้น ผู้ใช้จะไม่เห็นส่วนที่เหลือในเว็บ เว็บหนึ่งที่มีการตรวจสอบว่าผู้ใช้ล็อกอินแล้วหรือยัง ถ้ายังให้ redirect ไปยังหน้าล็อกอิน แต่ถ้าล็อกอินอยู่แล้วก็ให้แสดงเนื้อหาในเว็บนั้นเลย ตามโค๊ดด้านล่างนี้ครับ &#60;?php if (!$login) header("location:login.php"); ?&#62; เนื้อหาสำคัญที่จะเข้าถึงได้เฉพาะผู้ที่ล็อกอินแล้วเท่านั้น สิ่งที่เกิดขึ้นจริงคือ เมื่อ PHP แปลคำสั่งถึง header ที่กำหนด location แล้ว จะเป็นการส่ง HTTP Response [...]]]></description>
			<content:encoded><![CDATA[<p>คำสั่งการทำ Redirect ใน PHP นั้น อย่างที่เรารู้ ๆ กันอยู่ว่าเพียงแค่พิมพ์ว่า</p>
<pre class="php" name="code">header("location:http://blog.chonla.com");</pre>
<p>ซึ่งความจริงแล้ว มันเป็นการกำหนดค่า Location ลงไปใน HTTP Header นั่นเอง เรายังสามารถกำหนด Header อื่น ๆ ลงไปใน HTTP Header ได้อีก แต่วันนี้ผมจะพูดถึงเฉพาะ Location ครับ</p>
<p><span id="more-132"></span></p>
<p>มีหลายคนหลงคิดไปเองว่า การสั่ง Redirect ด้วยวิธีนี้นั้น ผู้ใช้จะไม่เห็นส่วนที่เหลือในเว็บ เว็บหนึ่งที่มีการตรวจสอบว่าผู้ใช้ล็อกอินแล้วหรือยัง ถ้ายังให้ redirect ไปยังหน้าล็อกอิน แต่ถ้าล็อกอินอยู่แล้วก็ให้แสดงเนื้อหาในเว็บนั้นเลย ตามโค๊ดด้านล่างนี้ครับ</p>
<pre class="php" name="code">&lt;?php
if (!$login)
    header("location:login.php");
?&gt;
เนื้อหาสำคัญที่จะเข้าถึงได้เฉพาะผู้ที่ล็อกอินแล้วเท่านั้น</pre>
<p>สิ่งที่เกิดขึ้นจริงคือ เมื่อ PHP แปลคำสั่งถึง header ที่กำหนด location แล้ว จะเป็นการส่ง HTTP Response 302 กลับไป ซึ่งหมายถึงสิ่งที่เว็บบราวเซอร์ต้องการนั้นอยู่อีกที่หนึ่ง รวมถึงระบุ URL ของหน้านั้น ๆ กลับไปให้ <strong><span style="color: #ff0000;">และยังทำการแปลส่วนที่เหลือจนจบและส่งกลับไปให้บราวเซอร์ด้วย</span></strong></p>
<p>เริ่มเห็นปัญหาแล้วหรือยังล่ะครับ ถ้าเริ่มเห็นอะไรเหมือนที่ผมเห็นแล้ว ลองไปดู <a title="LIVE DEMO : Clean Redirection" href="http://sandbox.chonla.com/redirect" target="_blank">LIVE DEMO</a> กันได้เลยครับ</p>
<p>คุณจะเห็นรายละเอียดใน LIVE DEMO ได้ง่ายขึ้นด้วยโปรแกรมประเภท HTTP Sniffer ครับ เช่น Fiddler, HTTPWatch หรือจะใช้พวก Packet Sniffer อย่างเช่น WireShark (Ethereal)</p>
<p>การแก้ไขปัญหามีหลายวิธีครับ ใน LIVE DEMO ผมใช้ exit() เป็นตัวแก้ไขปัญหา แต่ในความเป็นจริงแล้ว เราอาจจะใช้ if&#8230;else&#8230; ครอบไว้ก็ได้ครับ หรือใครมีวิธีอื่น ๆ อีกก็มาคุยกันได้ครับ</p>
<p>ตัวอย่างภาพที่ผมเซฟมาให้ดูนั้น เป็นภาพที่ได้จาก HTTPWatch ครับ ให้ลองเปรียบเทียบกันระหว่างส่วนที่เป็น Content กันระหว่างแบบที่ผมไม่ได้ใส่ exit() กับแบบที่ผมใส่ exit() เพื่อให้เห็นความแตกต่างของสิ่งที่ได้ส่งกลับมาให้บราวเซอร์ครับ</p>
<div id="attachment_133" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.chonla.com/wp-content/uploads/2008/11/loc.gif"><img class="size-medium wp-image-133" title="loc" src="http://blog.chonla.com/wp-content/uploads/2008/11/loc-300x134.gif" alt="Redirect ทั่ว ๆ ไป" width="300" height="134" /></a><p class="wp-caption-text">Redirect ทั่ว ๆ ไป</p></div>
<div id="attachment_134" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.chonla.com/wp-content/uploads/2008/11/locexit.gif"><img class="size-medium wp-image-134" title="locexit" src="http://blog.chonla.com/wp-content/uploads/2008/11/locexit-300x134.gif" alt="Redirect และปิดด้วย exit()" width="300" height="134" /></a><p class="wp-caption-text">Redirect และปิดด้วย exit()</p></div>
<p>นอกจากนี้แล้วการทำแบบนี้ยังทำให้ Perfomance สูงขึ้นด้วยครับ เพราะ PHP ไม่จำเป็นต้องประมวลผลคำสั่งส่วนที่เหลือนั่นเองครับ</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://blog.chonla.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.chonla.com/2008/11/redirect-%e0%b9%81%e0%b8%a5%e0%b9%89%e0%b8%a7%e0%b8%ad%e0%b8%a2%e0%b9%88%e0%b8%b2%e0%b8%84%e0%b8%b4%e0%b8%94%e0%b8%a7%e0%b9%88%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%84%e0%b8%a1%e0%b9%88%e0%b9%80%e0%b8%ab/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
