<?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>貳夢の弦 &#187; 程式語言</title>
	<atom:link href="http://blog.frost.tw/category/code/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.frost.tw</link>
	<description>夢醒之時，驚覺一切都是虛幻。前行吧！迷途者。</description>
	<lastBuildDate>Wed, 26 Oct 2011 13:28:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<atom:link rel='hub' href='http://blog.frost.tw/?pushpress=hub'/>
		<item>
		<title>Socket.IO + Express 生成聊天室</title>
		<link>http://blog.frost.tw/code/poston-2011-10-05/postid-1256</link>
		<comments>http://blog.frost.tw/code/poston-2011-10-05/postid-1256#comments</comments>
		<pubDate>Tue, 04 Oct 2011 16:08:15 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1256</guid>
		<description><![CDATA[最近又開始研究Node.JS，也因此開始接觸一些 Module 。 （實際上很久之前就接觸了，只是人懶拉……） 這次接觸的是有名的MVC Framework &#8211; Express 和 方便的 Socket.IO 。 說實在的，用來做聊天室真的「非常省時」 （想當初我慢慢寫程式，現在竟然只要半小時……） 大家自己用 NPM 安裝好 Express 後，就用 express -t ejs 生成一個專案吧！ （以下只會針對 Socket.IO 對聊天室製作的程式碼做說明喔！） app.js var io = require("socket.io").listen(app); //app 是 var app = express.createServer(); /* .... 略 &#8230; <a href="http://blog.frost.tw/code/poston-2011-10-05/postid-1256">Continue reading <span class="meta-nav">&#8594;</span></a><table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-10-30%2Fpostid-800&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 的 Comet Chat</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-07-11%2Fpostid-583&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">用 Node.js 寫聊天室的心得～</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-10%2Fpostid-582&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">談起 APE 和 node.js</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-12%2Fpostid-585&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 上的 MySQL</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p>最近又開始研究Node.JS，也因此開始接觸一些 Module 。</p>
<p>（實際上很久之前就接觸了，只是人懶拉……）</p>
<p>這次接觸的是有名的MVC Framework &#8211; Express 和 方便的 Socket.IO 。</p>
<p>說實在的，用來做聊天室真的「非常省時」</p>
<p>（想當初我慢慢寫程式，現在竟然只要半小時……）</p>
<p><span id="more-1256"></span></p>
<p>大家自己用 NPM 安裝好 Express 後，就用 express -t ejs 生成一個專案吧！</p>
<p>（以下只會針對 Socket.IO 對聊天室製作的程式碼做說明喔！）</p>
<p><strong> app.js </strong></p>
<pre class="brush:js">var io = require("socket.io").listen(app); //app 是 var app = express.createServer();

/* .... 略 .... */
app.listen(3000);

//Chat Room
var onlineList = {}; //建立一個線上列表物件

io.sockets.on('connection', function(socket){ //照官方的處理，基本上就是當Clinet連線時要做的事情

  socket.emit('reqNickname'); //向Client要求暱稱（其實應該用 join 而不是這樣，因為這樣會造成一些問題）
  socket.on('setNickname', function(nickname){ //當Client設定暱稱時
    if(!onlineList[nickname]){ //檢查暱稱是否重複
      socket.set('nickname', nickname, function(){ //Socket.IO 支援類似 Session 的儲存，這邊用來紀錄使用者暱稱
        onlineList[nickname] = socket; //這邊把 socket 物件存進去，用於之後的 Private Message 功能（Socket.IO 的每個 socket 都是對應個別 Client 的，不能搞混）
        socket.broadcast.emit('system', {'msg' : '<strong>' + nickname + '</strong> join!'}); //使用Broadcast可以發給除了自己外全部的Client (通知某使用者加入聊天室)
        socket.emit('ready'); //告訴Client可以開始聊天（此時發訊息等才會解鎖，本範例沒有特別限制）
      });
    }else{
      socket.emit('reqNickname'); //如果暱稱存在，則重新要求暱稱
    }
  });

  socket.on('chat', function(data){ //當Client發送聊天訊息
    socket.get('nickname', function(err, nickname){ //先取得暱稱
      if(!err){ //檢查是否有發生錯誤
        if(data.indexOf('/pm ') === 0){ //檢查是否為 /pm 的開頭，如果是判定為「私訊」
          var receiver = data.substr(4); //切割字串
          receiver = receiver.substr(0, receiver.indexOf(' ')); //取得收訊人的暱稱
          var chatMsg = data.substr(receiver.length + 5); //把剩下文字當要傳送的訊息
          if(onlineList[receiver]){ //檢查接收者是否存在
            onlineList[receiver].emit('pm', {'nickname' : nickname, 'msg' : chatMsg, 'rec' : receiver}); //發送給接收者私訊
            socket.emit('pm', {'nickname' : nickname, 'msg' : chatMsg, 'rec' : receiver}); //對Client也發送一次
          }else{
            socket.emit('system', {'msg' : '<strong>' + receiver + '</strong> not found.'});  //接收者不存在則出現錯誤訊息
          }
        }else{
          //一般情況正常聊天
          socket.broadcast.emit('chat', {'nickname' : nickname, 'msg' : data});
          socket.emit('chat', {'nickname' : nickname, 'msg' : data});
        }
      }
    });
  });

  socket.on('disconnect', function(){ //使用者斷開（系統）
    socket.get('nickname', function(err, nickname){ //先取得暱稱
      if(!err){
        if(onlineList[nickname]){ //確認是否存在使用者
          socket.broadcast.emit('system', {'msg' : '<strong>' + nickname + '</strong> exit.'}); //發送系統訊息告知其他使用者Client離線
        }
      }
    });
  });
});</pre>
<p><strong> index.ejs </strong></p>
<p>這邊用 jQuery 輔助，沒有做版面排版（CSS則略，因為除了設定 overflow:hide 之外其他沒有特別設定）</p>
<pre class="brush:html">&lt;script src="/socket.io/socket.io.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;h1&gt;&lt;%= title %&gt;&lt;/h1&gt;
&lt;p&gt;Welcome to &lt;%= title %&gt;&lt;/p&gt;

&lt;div id="chatArea"&gt;

&lt;/div&gt;
&lt;div id="chatForm"&gt;
	&lt;form action="" method="post" name="charForm" id="chat"&gt;
		&lt;span id="nickname"&gt;Unknow&lt;/span&gt; :
		&lt;input type="text" name="message" size="50" id="message" /&gt;
		&lt;input type="submit" name="send" value="Send" id="send" /&gt;
	&lt;/form&gt;
&lt;/div&gt;

&lt;script type="text/javascript"&gt;

    function scrollChatArea()
    {

    }

	var socket = io.connect("dmd.frost.tw", {'port':3030});

	var nickname = "Unknow";

	socket.on('reqNickname', function(){
		nickname = prompt('Type your nickname', '');
		socket.emit('setNickname', nickname);
	});

	socket.on('ready', function(){
		$("#nickname").html("&lt;strong&gt;" + nickname + "&lt;/strong&gt;");
		$("#chat").submit(function(e){

			var msg = $('input[name="message"]').val();
			socket.emit('chat', msg);
			$('input[name="message"]').val('').focus();

			return false;

		});
	});

	socket.on('chat', function(data){
		$("&lt;div&gt;&lt;strong&gt;" + data.nickname + "&lt;/strong&gt; Says: " + data.msg + "&lt;/div&gt;").hide().appendTo("#chatArea").fadeIn();
		$("#chatArea").scrollTop( $("#chatArea").innerHeight() );
	});

    socket.on('system', function(data){
    	$("&lt;div&gt;&amp;gt; " + data.msg + "&lt;/div&gt;").hide().appendTo("#chatArea").fadeIn();
		$("#chatArea").scrollTop( $("#chatArea").innerHeight() );
	});

    socket.on('pm', function(data){
        $("&lt;div&gt;&lt;strong&gt;" + data.nickname + "&lt;/strong&gt; to &lt;strong&gt;" + data.rec + "&lt;/strong&gt; Says: " + data.msg + "&lt;/div&gt;").hide().appendTo("#chatArea").fadeIn();
    	$("#chatArea").scrollTop( $("#chatArea").innerHeight() );
    });

&lt;/script&gt;</pre>
<p>前端使用方法和後端大同小異，都是用 on 和 emit 處理。<br />
如此一來，就完成一個有 PM 功能的聊天室了！<br />
（其實 Socket.IO 還支援 Room 的概念，只要把 Client 用 .join(&#8216;room name&#8217;) 就可以了！）<br />
有不清楚的部份請告知一下，我會解釋……<br />
（這篇文章就針對Server-Side做解釋而已，其他有問題還是可以問的～）</p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-10-30%2Fpostid-800&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 的 Comet Chat</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-07-11%2Fpostid-583&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">用 Node.js 寫聊天室的心得～</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-10%2Fpostid-582&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">談起 APE 和 node.js</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-12%2Fpostid-585&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-10-05%2Fpostid-1256">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 上的 MySQL</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-10-05/postid-1256/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>邪門Google運用 &#8211; JavaScript 留言板</title>
		<link>http://blog.frost.tw/code/poston-2011-05-29/postid-1199</link>
		<comments>http://blog.frost.tw/code/poston-2011-05-29/postid-1199#comments</comments>
		<pubDate>Sun, 29 May 2011 11:16:06 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1199</guid>
		<description><![CDATA[各位還記得之前分享的 Dropbox 應用 DropPages 嗎？ 之前網友說他一週就不能用，我就無視很久，不過今天檢查卻發現是可以免費使用的喔！ 不過，不能放PHP等程式上去一直是弦也頭痛的問題。 但今天弦也看到了一篇用 jQuery + YQL (Yahoo Query Language) + Google Spreadsheet 的應用教學，得到萌發啟發了？ 先看一下我們邪門的參考資料： http://tutorialzine.com/2010/08/dynamic-faq-jquery-yql-google-docs/ &#8211; YQL + Google Docs via jQuery 製作動態 FAQ （亂翻譯） http://p2pu.org/webcraft/node/27443/document/27520 &#8211; 就算是Google Spreadsheet 的 Form 我也有辦法讓他卡到陰（根本不是這麼一回事！） 光靠以上兩篇，我們就可以做出邪門的 純JavaScript 留言板摟！ &#8230; <a href="http://blog.frost.tw/code/poston-2011-05-29/postid-1199">Continue reading <span class="meta-nav">&#8594;</span></a><table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-02-18%2Fpostid-399&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Push4Free – JavaScript 方法(初次嘗試)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-11-08%2Fpostid-820&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">才…才不會讓你看全部呢！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-02-19%2Fpostid-402&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Push4Free – 簡易聊天室實作</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-09-03%2Fpostid-687&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">[GAE] 噗浪機器人 using JAVA</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p>各位還記得之前分享的 Dropbox 應用 DropPages 嗎？<br />
之前網友說他一週就不能用，我就無視很久，不過今天檢查卻發現是可以免費使用的喔！</p>
<p>不過，不能放PHP等程式上去一直是弦也頭痛的問題。<br />
但今天弦也看到了一篇用 jQuery + YQL (Yahoo Query Language) + Google Spreadsheet 的應用教學，得到<span style="color: #000000;"><del>萌發</del></span>啟發了？<br />
<span id="more-1199"></span>先看一下我們邪門的參考資料：<br />
<a href="http://tutorialzine.com/2010/08/dynamic-faq-jquery-yql-google-docs/" target="_blank">http://tutorialzine.com/2010/08/dynamic-faq-jquery-yql-google-docs/</a> &#8211; YQL + Google Docs via jQuery 製作動態 FAQ （亂翻譯）<br />
<a href="http://p2pu.org/webcraft/node/27443/document/27520" target="_blank">http://p2pu.org/webcraft/node/27443/document/27520</a> &#8211; 就算是Google Spreadsheet 的 Form 我也有辦法讓他卡到陰（根本不是這麼一回事！）</p>
<p>光靠以上兩篇，我們就可以做出邪門的 純JavaScript 留言板摟！</p>
<p>步驟一：</p>
<p>到你的 Google Docs 新增邪門的表單（和試算表一組的那個！？）<br />
然後設定一下欄位（本範例只有暱稱和留言兩個項目）</p>
<p><a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-50-55.png" rel="lightbox[1199]" title="2011-05-29 18 50 55"><img class="alignnone size-medium wp-image-1200" title="2011-05-29 18 50 55" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-50-55-300x110.png" alt="" width="300" height="110" /></a></p>
<p>步驟二：</p>
<p>取得表單的網址（Google 會給你一段 iframe 的 HTML 語法，用那段找出來～）</p>
<p><a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-51-07.png" rel="lightbox[1199]" title="2011-05-29 18 51 07"><img class="alignnone size-full wp-image-1201" title="2011-05-29 18 51 07" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-51-07.png" alt="" width="166" height="102" /></a></p>
<p><a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-51-33.png" rel="lightbox[1199]" title="2011-05-29 18 51 33"><img class="alignnone size-medium wp-image-1202" title="2011-05-29 18 51 33" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-51-33-300x87.png" alt="" width="300" height="87" /></a><br />
（網址是 src="網址" 的部份）</p>
<p>步驟三：</p>
<p>從表單找出送出的位置，還有各個欄位的 name 是多少。<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-52-07.png" rel="lightbox[1199]" title="2011-05-29 18 52 07"><img class="alignnone size-medium wp-image-1203" title="2011-05-29 18 52 07" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-52-07-300x244.png" alt="" width="300" height="244" /></a></p>
<p><a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-52-47.png" rel="lightbox[1199]" title="2011-05-29 18 52 47"><img class="alignnone size-medium wp-image-1204" title="2011-05-29 18 52 47" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-52-47-300x95.png" alt="" width="300" height="95" /></a></p>
<p>如果有 Firebug 或者使用較新版的Chrome/Safari可以點選右鍵&gt;觀察元素，比較好找。<br />
（action="表單送出位置" 還有各欄位的 name 值）</p>
<p>步驟四：</p>
<p>轉換成HTML頁面（美工請自己負責喔～）</p>
<p>引用 jQuery 程式庫，這邊使用 1.4 是因為教學的版本，各位可以自行選用新版。</p>
<p><a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-54-17.png" rel="lightbox[1199]" title="2011-05-29 18 54 17"><img class="alignnone size-medium wp-image-1205" title="2011-05-29 18 54 17" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-54-17-300x9.png" alt="" width="300" height="9" /></a></p>
<p>建構前端介面（表單、留言區塊）<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-54-47.png" rel="lightbox[1199]" title="2011-05-29 18 54 47"><img class="alignnone size-medium wp-image-1206" title="2011-05-29 18 54 47" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-54-47-300x63.png" alt="" width="300" height="63" /></a></p>
<p>撰寫 JavaScript 部份（使用YQL輔助）<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-55-05.png" rel="lightbox[1199]" title="2011-05-29 18 55 05"><img class="alignnone size-medium wp-image-1207" title="2011-05-29 18 55 05" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-55-05-300x149.png" alt="" width="300" height="149" /></a></p>
<p>上面的 csvURL 是從發布表單的地方取得：<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-58-32.png" rel="lightbox[1199]" title="2011-05-29 18 58 32"><img class="alignnone size-medium wp-image-1209" title="2011-05-29 18 58 32" src="http://blog.frost.tw/wp-content/uploads/2011/05/2011-05-29-18-58-32-300x159.png" alt="" width="300" height="159" /></a><br />
（選用 csv格式）</p>
<p>接著設定 YQL 的查詢網址。<br />
?q= 之後是查詢語法，這邊使用的是<br />
SELECT * FROM csv WHERE url = &#8216;csvURL(有經過 urlEncode)&#8217; AND column = &#8216;time, nickname, content&#8217;<br />
這樣就代表我用 csv 格式查詢，從我傳入的 URL 位置，並且依序設定欄位名稱為 time, nickname, content</p>
<p>最後用 jQuery 的 Ajax 功能取得 JSON 傳回，並且用 $.each 依序處理傳回值。<br />
（用FireFox可以觀察到物件在 msg.query.result.row 裡面，不過只有一筆資料會發生錯誤就是了……）</p>
<p>註：在 each 的處理函式讓他傳入 key 檢查是否 == 0 來把 Google Spreadsheet 預設的欄位跳過。</p>
<p>最後做偵測處理。<br />
1. 送出表單會跑到 Google 頁面，所以讓 form 指向設定的框架（隱藏）<br />
2. 用 jQuery 偵測 onsubmit 事件，送出後設定 submitted 為 true<br />
3. 此時隱藏的 iframe 會因為送出表單觸發，接著發現 submitted 為 true 於是重新整理頁面。<br />
4. 留言板流程運作完畢</p>
<p>這樣一來就可以留言了，中間有一些部份需要多加思考。<br />
註：使用 YQL 會無法即時，而 jQuery Plugin 的 jSpreadheet 版本過舊，各位可能要自己處理 CSV 格式化。</p>
<p>範例：<a href="http://dl.dropbox.com/u/4023935/Web%20Showcase/evil-Google-Guestbook.html" target="_blank">http://dl.dropbox.com/u/4023935/Web%20Showcase/evil-Google-Guestbook.html</a></p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-02-18%2Fpostid-399&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Push4Free – JavaScript 方法(初次嘗試)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-11-08%2Fpostid-820&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">才…才不會讓你看全部呢！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-02-19%2Fpostid-402&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Push4Free – 簡易聊天室實作</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-09-03%2Fpostid-687&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-29%2Fpostid-1199">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">[GAE] 噗浪機器人 using JAVA</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-05-29/postid-1199/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>C++ 重新開始~</title>
		<link>http://blog.frost.tw/code/poston-2011-05-16/postid-1182</link>
		<comments>http://blog.frost.tw/code/poston-2011-05-16/postid-1182#comments</comments>
		<pubDate>Mon, 16 May 2011 10:45:14 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[校園]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1182</guid>
		<description><![CDATA[今天開始，我們這群考上學校的大學生可以說是「很悶」 而我又沒有筆電，只好默默的看書拉！ 幸好老媽昨晚有順便幫我拿書，不然今天把書看完就不知道該做什麼了！ 今日閱讀：「C++程式設計藝術」 高一那時有簡單學過，不過並沒有去深入研究。 頂多只做到寫一個 Socket Server/Client 的程度而已。 （雖然後來有簡單嘗試用 PHP Send Command 給 Socket Server 去控制 Winamp 的播放/暫停不過也只是小玩一下～） 這本書一開始就建立起物件導向觀念。 也因為是教材書，所以寫的真的很清楚。 （當一般書來看也是非常棒的呢！） 這邊就簡單寫個小程式小試身手好了！ （不過沒有編譯環境，就看哪位網友願意幫我試試結果摟！） 下面程式基本上都依照書中要求撰寫出高可讀性的程式碼。 （不過也有一些是自己習慣帶入的……） /** * Simple ATM * * A simple ATM system */ #include&#60;iostream&#62; #include&#60;string&#62; using &#8230; <a href="http://blog.frost.tw/code/poston-2011-05-16/postid-1182">Continue reading <span class="meta-nav">&#8594;</span></a><table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-11-30%2Fpostid-860&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">新書入手！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-05-03%2Fpostid-519&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">懶散的一天！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-10-12%2Fpostid-762&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">精神力戰爭</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-06-17%2Fpostid-549&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">校園生活中難免會有的「笑話」</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p>今天開始，我們這群考上學校的大學生可以說是「很悶」<br />
而我又沒有筆電，只好默默的看書拉！</p>
<p>幸好老媽昨晚有順便幫我拿書，不然今天把書看完就不知道該做什麼了！<br />
今日閱讀：「C++程式設計藝術」<br />
<span id="more-1182"></span><br />
高一那時有簡單學過，不過並沒有去深入研究。<br />
頂多只做到寫一個 Socket Server/Client 的程度而已。<br />
（雖然後來有簡單嘗試用 PHP Send Command 給 Socket Server 去控制 Winamp 的播放/暫停不過也只是小玩一下～）</p>
<p>這本書一開始就建立起物件導向觀念。<br />
也因為是教材書，所以寫的真的很清楚。<br />
（當一般書來看也是非常棒的呢！）</p>
<p>這邊就簡單寫個小程式小試身手好了！<br />
（不過沒有編譯環境，就看哪位網友願意幫我試試結果摟！）</p>
<p>下面程式基本上都依照書中要求撰寫出高可讀性的程式碼。<br />
（不過也有一些是自己習慣帶入的……）</p>
<pre class="brush: cpp">
/**
 * Simple ATM
 *
 * A simple ATM system
 */
#include&lt;iostream&gt;
#include&lt;string&gt;

using namespace std;

class SimpleATM
{

  public:
    void function SimpleATM(string initUsername) //Construct
    {
      setUsername(initUsername);
    }

    void function setUsername(string setUsername)
    {
      username = setUsername;
    }

    string function getUsername()
    {
      return username;
    }

    int function getBalance()
    {
        return balance;
    }

    void setBalance(int setBalance)
    {
      balance = setBalance;
    }

    boolean function saveMoney(int moneyPlus)
    {
      if(moneyPlus > 0){ //check is a valid value
        setBalance(getBalance() + moneyPlus);
        return true;
      }else{
        return false;
      }
    }

   boolean function cashOut(int moneyGet)
   {
      if(moneyGet > 0){ //check is a valid value
        setBalance(getBalance() - moneyGet);
        return true;
      }else{
        return false;
      }
   }

  void function displayBalance()
  {
    cout << "Hello, " << getUsername() << ".\nYour balance is " << getBalance() << endl;
  }
  private:
    int balance;
    string username;

}; //容易忘記的部份

void main()
{
  SimpleATM aotoki("Aotoki");
  aotoki.displayBalance();
  aotoki.saveMoney(100);
  aotoki.displayBalance();
  aotoki.cashOut(25);
  aotoki.displayBalance();
}
</pre>
<p>會寫這段是因為以前有網友問過，所以就拿來練習看看～<br />
（找個時間編譯看看能不能正常運作好了……）</p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-11-30%2Fpostid-860&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">新書入手！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-05-03%2Fpostid-519&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">懶散的一天！</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-10-12%2Fpostid-762&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">精神力戰爭</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-06-17%2Fpostid-549&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-05-16%2Fpostid-1182">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">校園生活中難免會有的「笑話」</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-05-16/postid-1182/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSApp.US &#8211; 免費的 Node.JS 伺服器</title>
		<link>http://blog.frost.tw/code/poston-2011-03-07/postid-1141</link>
		<comments>http://blog.frost.tw/code/poston-2011-03-07/postid-1141#comments</comments>
		<pubDate>Mon, 07 Mar 2011 10:58:15 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[網站]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1141</guid>
		<description><![CDATA[前幾天，弦也注意到 Node.JS 的 Wiki 上 Hosting 的列表又多了些。 抑或是說這次弦也仔細去閱讀這個列表，發現 JSApp.US 是唯一一個目前可以使用的 Node.JS Hosting 不過，什麼是 Node.JS 大家可能會不解。 以弦也最近更新的知識，他應該是一個 Server Side JavaScript 而且支援 Evented I/O 的程式語言。 那 Node.JS 可以做什麼呢？ 此時，就要舉大家介紹 Node.JS 最常提到的一個網站 &#8211; Plurk 了！ 噗浪就是使用 Node.JS 開發的喔！ 也因此，他擁有即時更新的功能。 這就是所謂的 Comet 技術實踐吧！ 不過，所謂的 &#8230; <a href="http://blog.frost.tw/code/poston-2011-03-07/postid-1141">Continue reading <span class="meta-nav">&#8594;</span></a><table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-10-30%2Fpostid-800&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 的 Comet Chat</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-12%2Fpostid-585&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 上的 MySQL</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-07-11%2Fpostid-583&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">用 Node.js 寫聊天室的心得～</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-10%2Fpostid-582&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">談起 APE 和 node.js</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p>前幾天，弦也注意到 Node.JS 的 Wiki 上 Hosting 的列表又多了些。<br />
抑或是說這次弦也仔細去閱讀這個列表，發現 JSApp.US 是唯一一個目前可以使用的 Node.JS Hosting</p>
<p>不過，什麼是 Node.JS 大家可能會不解。<br />
以弦也最近更新的知識，他應該是一個 Server Side JavaScript 而且支援 Evented I/O 的程式語言。<br />
<span id="more-1141"></span><br />
那 Node.JS 可以做什麼呢？<br />
此時，就要舉大家介紹 Node.JS 最常提到的一個網站 &#8211; Plurk 了！<br />
噗浪就是使用 Node.JS 開發的喔！</p>
<p>也因此，他擁有即時更新的功能。<br />
這就是所謂的 Comet 技術實踐吧！</p>
<p>不過，所謂的 Comet 又是什麼呢？<br />
簡單說，就是利用 Ajax 來做 Socket 的事情。<br />
我們又以 Client 和 Server 分為 Poll 和 Push 兩個動作。<br />
Push 是以伺服器發訊息給客戶端，以往都是被動。<br />
而 Poll 是客戶端請求資料，過去時代的聊天室就是重複 Poll 了！</p>
<p>現在利用 Ajax 模擬 Http 請求，對伺服器做 Poll (Long)<br />
而 Node.JS 則檢查是否有資料，有資料時才做 Push 回去給客戶端。<br />
（因為 Ajax 特性，沒有回應時就不會觸發事件，可以一直等待回應。）</p>
<p>而這樣一來一往的動作，就很類似 Socket 的 Listen Request 之類的動做。<br />
這種技術則稱為 Comet 技術。</p>
<p>Node.JS 則是非常適合用於實踐這個技術的 Server Side 語言。</p>
<p>那麼，回到正題。</p>
<p><strong>JSApp.US 網站資料</strong><br />
網址：<a href="http://jsapp.us" target="_blank">http://jsapp.us<br />
</a>運行模式：VM處理（用戶程式跑在 Child Porcess 中，不干預主程式）<br />
限制：部份 Module 無法載入，http modules 有限使用（createServer&amp;Client都只能用 Port 80）<br />
費用：無（如果想租VPS可以參考開發者的推薦連結，讓這個服務繼續下去。）</p>
<p>那麼，期待大家的作品摟！</p>
<p>官方聊天室範例（使用 node-router 模組 *此為額外擴充）<br />
<a href="http://chat.jsapp.us" target="_blank">http://chat.jsapp.us</a></p>
<p>弦也測試的聊天室（自行處理 Router）<br />
<a href="http://jsapp.frost.tw/" target="_blank">http://jsapp.frost.tw/</a></p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">您可能也喜歡：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-10-30%2Fpostid-800&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 的 Comet Chat</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-12%2Fpostid-585&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Node.js 上的 MySQL</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2010-07-11%2Fpostid-583&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">用 Node.js 寫聊天室的心得～</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.frost.tw%2Flife%2Fposton-2010-07-10%2Fpostid-582&from=http%3A%2F%2Fblog.frost.tw%2Fcode%2Fposton-2011-03-07%2Fpostid-1141">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">談起 APE 和 node.js</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-03-07/postid-1141/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>《弦也式插件開發術》序．Plugin 概論</title>
		<link>http://blog.frost.tw/code/poston-2011-02-22/postid-1120</link>
		<comments>http://blog.frost.tw/code/poston-2011-02-22/postid-1120#comments</comments>
		<pubDate>Tue, 22 Feb 2011 11:16:42 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[筆記]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1120</guid>
		<description><![CDATA[因為我很懶惰，所以就把昨晚在討論版上發表的文章轉貼過來啦～ 這篇文章我想應該還有錯誤的地方。 （大概是我理解錯誤） 不過Discuz/WordPress的插件運行，大致上就是這種構造。 （註：注意事項那段真的是「有人很過份，把別人文章、錄好影片都轉貼」所以我才特地加上的……） 注意事項： 本文章為原創文章，假使未經原作者同意而任意轉載於本站以外的站點，原作者有權以法律途徑要求賠償。 假使欲轉載本文至本站以外之站點，需附上原文網址以及作者網站。 《弦也式插件開發術》序．Plugin 概論 @Author: 蒼時弦や @Website: http://frost.tw/ 一、Plugin 簡介 何謂 Plugin (插件) 呢？ 就字面上的意思，即是「插入」，即使這樣說明也難以理解是什麼意思。 以生活上的方式解釋，就像是樂高一般，將不同大小、形狀的方塊插入，組合出一個形體。 以線上遊戲來看，也許就是像「裝備」一樣，依照你的需求裝備上不同的道具。 簡而言之，插件提供了架站者個人化的選擇，也強化了架站機的功能。 二、何為 Module (模組) 在早期 Xoops, phpBB 時代，會有所謂Module或者Mod這類名詞。 他們與插件的差異，應該就是所謂的 Hook [註] 的使用。 模組就像是一台機器的零件一般，在你需要的時候放進去，組合成一台機器，或者改裝這個機器。 但插件則不同了，他像是晶片或者軟體一般，只需要安裝上去，就會自動調整你的機器。 以現在Server(主機)的CPU能力來看，即使使用Plugin的方式擴充，也不會碰上運算效率低下的問題。 （筆者推測早期模組的使用在於減少CPU使用，以及Hook技術的處理尚未成熟） 註：Hook &#8230; <a href="http://blog.frost.tw/code/poston-2011-02-22/postid-1120">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>因為我很懶惰，所以就把昨晚在討論版上發表的文章轉貼過來啦～<br />
這篇文章我想應該還有錯誤的地方。<br />
（大概是我理解錯誤）</p>
<p>不過Discuz/WordPress的插件運行，大致上就是這種構造。<br />
（註：注意事項那段真的是「有人很過份，把別人文章、錄好影片都轉貼」所以我才特地加上的……）<br />
<span id="more-1120"></span></p>
<p><strong>注意事項：</strong><br />
本文章為原創文章，假使未經原作者同意而任意轉載於本站以外的站點，原作者有權以法律途徑要求賠償。<br />
<span style="color: #ff0000;"><strong>假使欲轉載本文至本站以外之站點，需附上原文網址以及作者網站。</strong></span></p>
<p><strong>《弦也式插件開發術》序．Plugin 概論</strong></p>
<p>@Author: 蒼時弦や<br />
@Website: <a href="http://frost.tw/" target="_blank">http://frost.tw/</a></p>
<p><strong>一、Plugin 簡介</strong><br />
何謂 Plugin (插件) 呢？<br />
就字面上的意思，即是「插入」，即使這樣說明也難以理解是什麼意思。<br />
以生活上的方式解釋，就像是樂高一般，將不同大小、形狀的方塊插入，組合出一個形體。<br />
以線上遊戲來看，也許就是像「裝備」一樣，依照你的需求裝備上不同的道具。</p>
<p>簡而言之，插件提供了架站者個人化的選擇，也強化了架站機的功能。</p>
<p><strong>二、何為 Module (模組)</strong><br />
在早期 Xoops, phpBB 時代，會有所謂Module或者Mod這類名詞。<br />
他們與插件的差異，應該就是所謂的 Hook [註] 的使用。<br />
模組就像是一台機器的零件一般，在你需要的時候放進去，組合成一台機器，或者改裝這個機器。<br />
但插件則不同了，他像是晶片或者軟體一般，只需要安裝上去，就會自動調整你的機器。</p>
<p>以現在Server(主機)的CPU能力來看，即使使用Plugin的方式擴充，也不會碰上運算效率低下的問題。<br />
（筆者推測早期模組的使用在於減少CPU使用，以及Hook技術的處理尚未成熟）</p>
<p>註：Hook &#8211; 鉤子，是與Plugin密切關係的一項處理，他可以協助Plugin在特定的位置增加或修改動作、訊息。</p>
<p><strong>三、Hook的概念</strong><br />
筆者之後將要介紹的WordPress, Discuz等架站機，都是使用 Hook 作為擴充的架站機。<br />
那麼，就必須瞭解 Hook 在 Plugin 上的意義了！</p>
<p>鉤子像是什麼東西呢？<br />
簡單的形容他，大概就像是一個標記，讓程式可以識別。<br />
不過，這樣也許還是非常抽象，但是筆者也想不到什麼好方法可以解釋Hook的意義。</p>
<p>而 Hook 是如何與 Plugin 作為關聯呢？<br />
這是一個非常簡單的概念，就如同前文所述的「標記」這個動作。<br />
不論是WordPress還是Discuz他們皆有共通的特色。<br />
那就是在特定的「點」有一段程式碼會運行某個 Hook 並且去喚醒 Plugin 內的程式碼。</p>
<p>也許 Hook 可以當作是鬧鐘，在某個時間把你叫醒一般。<br />
以 WordPress 的 Hook 為例子來看。<br />
在WordPress程式大多運行完畢後，會呼叫 init 這個鉤子（每個鉤子都有自己的名稱，這個是名為「初始化」的鉤子）<br />
此時，只要你的Plugin設定某段程式碼是 init 這個鉤子所呼叫的片段，那麼在 init 運行時，就會連同你的鉤子一同執行。</p>
<p><strong>四、WordPress的Hook (主動式)</strong><br />
就筆者認為，在WordPress去追加一個動作的方式來看，在WordPress上比較為「主動」<br />
何為主動呢？<br />
也就是需要開發者自行追加，才會有效果。</p>
<p>這邊我們以一小段程式碼為例子：</p>
<pre class="brush: php">&lt;?php
function my_hook()
{
//Here will do something...
}
add_action('init', 'my_hook');
?&gt;</pre>
<p>上述的程式碼將會在 init 這個 hook 點運行時，一併運行 my_hook 這個函式。<br />
這也就是 WordPress 的Hook運行方式。<br />
（沒有使用 add_action 或 add_filter 去告訴系統，有片段要再某個Hook運行，系統就不會去運行。）</p>
<p><strong>五、Discuz的Hook (被動式)</strong><br />
為什麼筆者稱Discuz的Hook為被動式呢？<br />
因為當開發者寫好他的程式碼片段後，只要 Hook 點運行，就會被呼叫。<br />
完全不需要自己主動去告訴Hook要運行的動作。</p>
<p>[註] 因為筆者長期沒有開發 Discuz 插件，因此以官方文件的代碼來解釋。</p>
<pre class="brush: php">//全局脚本嵌入点类
class plugin_identifier_CURSCRIPT[_DO] extends plugin_identifier {

function HookId_1() {
......
return ...;
}

function HookId_2() {
......
return ...;
}

......

}</pre>
<p>以上方程式碼的片段來看，插件都一律以 plugin_插件識別名 來做命名（物件）<br />
而對某個 Hook 新增動作時，就會以 plugin_插件識別名_動作文件 來做命名（物件）<br />
而 HookId 就是每個 Hook 的識別名稱了！<br />
如 viewthread 為閱讀文章相關的 Hook 動作。</p>
<p><strong>六、開發WordPress &amp; Discuz 插件的要點</strong><br />
使用 Hook 將會是這兩類架站機的重要觀念。<br />
並且要分別習慣兩種架站機其產生訊息的方式以及差異。<br />
如 WordPress 並無版模系統，並且有 Action Hook 以及 Filter Hook 兩種。<br />
Action Hook 單純做運算處理，屬於 Controller/Model 層面（控制/模型層）<br />
Filter Hook 則是負責輸出處理，屬於 Views 層面（視圖層）</p>
<p>而在Discuz上，一般訊息的顯示都以呼叫函式產生。<br />
大部分的返回訊息也是以 return 就能夠輸出。<br />
（某種意義上，在Discuz大部分的Hook都是Filter Hook）<br />
當想輸出頁面時，也需要使用特定函式才可輸出（還需建立版模）</p>
<p>不過，共通的要點就是熟悉這些 Hook 的位置以及使用時機。<br />
（在WordPress上有優先權的設置，而Discuz則無。）</p>
<p><strong>七、小結</strong><br />
雖然網路上的Plugin變化非常多，也有許多五花八門的運用。<br />
但探究其原理，實際上只有非常少的內容。<br />
整個 Plugin 技術，都是圍繞在 Hook 這個部份上。<br />
其餘的都是單純的 PHP 開發，只不過規模比較小而已。</p>
<p>當熟悉 Hook 之後，往後的 Plugin 開發就算是通行無阻了！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-02-22/postid-1120/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress 的「裁切」功能</title>
		<link>http://blog.frost.tw/code/poston-2011-02-14/postid-1107</link>
		<comments>http://blog.frost.tw/code/poston-2011-02-14/postid-1107#comments</comments>
		<pubDate>Mon, 14 Feb 2011 11:09:56 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=1107</guid>
		<description><![CDATA[最近因為案子的關係，需要做一個「幻燈片」功能在 WordPress 首頁上。 不過，裁切圖片、縮圖的問題倒是很困擾我的。 再加上我還未嘗試過「讀取特色圖片以外」的圖檔，以及「自行上傳圖檔」的處理。 不過，當我看到 WordPress 的 Custom Header 功能後，我馬上知道我該怎麼做了！ WordPress 內建一款名為 imgAreaSelect 的切圖 jQuery Plguin 不過，似乎只有在使用 Custom Header 時比較容易見到他。 （據說在媒體庫上傳時也能使用，不過大家通常都是隨文章上傳吧……） 那麼，我想另外呼叫又該如何做呢？ 以 WordPress 的作法，是三部曲。 上傳、裁切、儲存三個部份。 首先我們來看看裁切中的畫面。 實際上用起來沒有 Flash 的靈敏，不過已經算很方便了！ 當裁切完成後，製作成 Slideshow 時，效果又如何呢？ （某弦案子的製成品，會如下圖所示……） 抓取的區域會被切下（圖片解析度不夠大時，會被拉大，裁切時請注意喔！） 那麼，分別來解釋這個「三部曲」吧！ （大部分原始碼都來自 Custom Header &#8230; <a href="http://blog.frost.tw/code/poston-2011-02-14/postid-1107">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>最近因為案子的關係，需要做一個「幻燈片」功能在 WordPress 首頁上。<br />
不過，裁切圖片、縮圖的問題倒是很困擾我的。<br />
再加上我還未嘗試過「讀取特色圖片以外」的圖檔，以及「自行上傳圖檔」的處理。</p>
<p>不過，當我看到 WordPress 的 Custom Header 功能後，我馬上知道我該怎麼做了！<br />
<span id="more-1107"></span><br />
WordPress 內建一款名為 imgAreaSelect 的切圖 jQuery Plguin<br />
不過，似乎只有在使用 Custom Header 時比較容易見到他。<br />
（據說在媒體庫上傳時也能使用，不過大家通常都是隨文章上傳吧……）</p>
<p>那麼，我想另外呼叫又該如何做呢？<br />
以 WordPress 的作法，是三部曲。</p>
<p>上傳、裁切、儲存三個部份。</p>
<p>首先我們來看看裁切中的畫面。<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/02/2011-02-14-18-43-26.png" rel="lightbox[1107]" title="幻燈片 - 裁切中"><img class="alignnone size-medium wp-image-1108" title="幻燈片 - 裁切中" src="http://blog.frost.tw/wp-content/uploads/2011/02/2011-02-14-18-43-26-179x300.png" alt="" width="179" height="300" /></a></p>
<p>實際上用起來沒有 Flash 的靈敏，不過已經算很方便了！</p>
<p>當裁切完成後，製作成 Slideshow 時，效果又如何呢？<br />
（某弦案子的製成品，會如下圖所示……）<br />
<a href="http://blog.frost.tw/wp-content/uploads/2011/02/2011-02-14-18-46-26.png" rel="lightbox[1107]" title="幻燈片 - 展示"><img class="alignnone size-medium wp-image-1109" title="幻燈片 - 展示" src="http://blog.frost.tw/wp-content/uploads/2011/02/2011-02-14-18-46-26-300x173.png" alt="" width="300" height="173" /></a></p>
<p>抓取的區域會被切下（圖片解析度不夠大時，會被拉大，裁切時請注意喔！）</p>
<p>那麼，分別來解釋這個「三部曲」吧！<br />
（大部分原始碼都來自 Custom Header 的原始碼、弦也Slideshow的原始碼）</p>
<p><strong>第一步，上傳。</strong><br />
（簡單建立一個上傳的From即可）</p>
<pre class="brush:html">&lt;h3&gt;新增幻燈片&lt;/h3&gt;
 &lt;form enctype="multipart/form-data" id="upload-form" method="post" action="&lt;?php echo esc_attr( add_query_arg( 'step', 2 ) ) ?&gt;"&gt;
 &lt;label for="upload"&gt;&lt;?php _e( 'Choose an image from your computer:' ); ?&gt;&lt;/label&gt;&lt;br /&gt;
 &lt;input type="file" id="upload" name="import" /&gt;&lt;br /&gt;
 &lt;label for="title"&gt;標題&lt;/label&gt;
 &lt;input type="text" name="title" /&gt;&lt;br /&gt;
 &lt;label for="link"&gt;連結&lt;/label&gt;
 &lt;input type="text" name="link" /&gt;&lt;br /&gt;
 &lt;label for="des"&gt;說明&lt;/label&gt;
 &lt;textarea name="des" cols="20" rows="5"&gt;&lt;?php echo $slides['des']; ?&gt;&lt;/textarea&gt;&lt;br /&gt;
 &lt;?php wp_nonce_field( 'moho-slide', '_wpnonce-moho-slide' ) ?&gt;
 &lt;input type="submit" value="&lt;?php esc_attr_e( 'Upload' ); ?&gt;" /&gt;
 &lt;/form&gt;</pre>
<p>esc_attr( add_query_arg( &#8216;step&#8217;, 2 ) ) 會產生一個 http://網址/wp-admin/目前頁面.php?page=插件註冊名&amp;step=2 的查詢串。<br />
要判斷目前為第幾步，使用 if(intval($_GET['step']) == 2) 這類判斷式即可。</p>
<p><strong>第二步，裁切。</strong><br />
（要先用引入相關JS/Style才能使用，弦也是寫在Themes附上的模組，所以直接在 functions.php 加入下列語法）</p>
<pre class="brush:php">wp_enqueue_style('imgareaselect');
wp_enqueue_script('imgareaselect');</pre>
<p>接收上傳檔案的地方要先做第一階段處理（儲存檔案、計算放大縮小倍率、插入到媒體庫）</p>
<pre class="brush:php">check_admin_referer('moho-slide', '_wpnonce-moho-slide');
 $overrides = array('test_form' =&gt; false);

 if(!empty($_FILES['import']['tmp_name'])){
 $file = wp_handle_upload($_FILES['import'], $overrides);

 if ( isset($file['error']) )
 wp_die( $file['error'],  __( 'Image Upload Error' ) );

 $url = $file['url'];
 $type = $file['type'];
 $file = $file['file'];
 $filename = basename($file);
 }

 if(isset($_POST['ss_id']) &amp;&amp; isset($_POST['attachment_id'])){
 if(!empty($_POST['title']) &amp;&amp; !empty($_POST['des'])){
 $slides[$_POST['ss_id']]['title'] = htmlspecialchars($_POST['title']);
 $slides[$_POST['ss_id']]['link'] = htmlspecialchars($_POST['link']);
 $slides[$_POST['ss_id']]['des'] = htmlspecialchars($_POST['des']);
 update_option('slideshow', $slides);
 if(empty($_FILES['import']['tmp_name'])){
 call_step_1($slides);
 return;
 }
 }
 }else{
 if(!empty($_POST['title']) &amp;&amp; !empty($_POST['des']) &amp;&amp; !empty($_FILES['import']['tmp_name'])){
 $slide = array(
 'title' =&gt; htmlspecialchars($_POST['title']),
 'link' =&gt; htmlspecialchars($_POST['link']),
 'des' =&gt; htmlspecialchars($_POST['des']),
 'attachment_id' =&gt; $id,
 'imgurl' =&gt; $url
 );
 array_push($slides, $slide);
 update_option('slideshow', $slides);
 $_POST['ss_id'] = count($slides)-1;
 }else{
 call_step_1($slides);
 return;
 }

 }

 $object = array(
 'post_title' =&gt; $filename,
 'post_content' =&gt; $url,
 'post_mime_type' =&gt; $type,
 'guid' =&gt; $url);

 //Save Data
 $id = wp_insert_attachment($object, $file);

 list($width, $height, $type, $attr) = getimagesize( $file );

 if ( $width == 600 &amp;&amp; $height == 300 ) {
 // Add the meta-data
 wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );

 set_theme_mod('header_image', esc_url($url));
 do_action('wp_create_file_in_uploads', $file, $id); // For replication
 return $this-&gt;finished();
 } elseif ( $width &gt; 600 ) {
 $oitar = $width / 600;
 $image = wp_crop_image($file, 0, 0, $width, $height, 600, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
 if ( is_wp_error( $image ) )
 wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );

 $image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication

 $url = str_replace(basename($url), basename($image), $url);
 $width = $width / $oitar;
 $height = $height / $oitar;
 } else {
 $oitar = 1;
 }</pre>
<p>完成後產生一個只有 Submit 的表單，其餘都是隱藏值（把切割資訊傳給 WordPress 處理）<br />
（而還需要 jQuery 幫忙處理表單值和啟動裁切功能）</p>
<pre class="brush:html">&lt;form method="post" action="&lt;?php echo esc_attr(add_query_arg('step', 3)); ?&gt;"&gt;
 &lt;p&gt;&lt;?php _e('Choose the part of the image you want to use as your header.'); ?&gt;&lt;/p&gt;
 &lt;p&gt;&lt;strong&gt;&lt;?php _e( 'You need Javascript to choose a part of the image.'); ?&gt;&lt;/strong&gt;&lt;/p&gt;

 &lt;div id="crop_image" style="position: relative"&gt;
 &lt;img src="&lt;?php echo esc_url( $url ); ?&gt;" id="upload" width="&lt;?php echo $width; ?&gt;" height="&lt;?php echo $height; ?&gt;" /&gt;
 &lt;/div&gt;

 &lt;p&gt;
 &lt;input type="hidden" name="x1" id="x1" value="0"/&gt;
 &lt;input type="hidden" name="y1" id="y1" value="0"/&gt;
 &lt;input type="hidden" name="width" id="width" value="&lt;?php echo esc_attr( $width ); ?&gt;"/&gt;
 &lt;input type="hidden" name="height" id="height" value="&lt;?php echo esc_attr( $height ); ?&gt;"/&gt;
 &lt;input type="hidden" name="attachment_id" id="attachment_id" value="&lt;?php echo esc_attr( $id ); ?&gt;" /&gt;
 &lt;input type="hidden" name="oitar" id="oitar" value="&lt;?php echo esc_attr( $oitar ); ?&gt;" /&gt;
 &lt;input type="hidden" name="ss_id" id="ss_id" value="&lt;?php echo $_POST['ss_id']; ?&gt;" /&gt;
 &lt;?php wp_nonce_field( 'moho-slide-crop' ) ?&gt;
 &lt;input type="submit" value="&lt;?php esc_attr_e( 'Crop and Publish' ); ?&gt;" /&gt;
 &lt;/p&gt;
 &lt;/form&gt;
 &lt;script type="text/javascript"&gt;
 /* &lt;![CDATA[ */
 function onEndCrop( coords ) {
 jQuery( '#x1' ).val(coords.x);
 jQuery( '#y1' ).val(coords.y);
 jQuery( '#width' ).val(coords.w);
 jQuery( '#height' ).val(coords.h);
 }

 jQuery(document).ready(function() {
 var xinit = &lt;?php echo 600; ?&gt;;
 var yinit = &lt;?php echo 300; ?&gt;;
 var ratio = xinit / yinit;
 var ximg = jQuery('img#upload').width();
 var yimg = jQuery('img#upload').height();

 if ( yimg &lt; yinit || ximg &lt; xinit ) {
 if ( ximg / yimg &gt; ratio ) {
 yinit = yimg;
 xinit = yinit * ratio;
 } else {
 xinit = ximg;
 yinit = xinit / ratio;
 }
 }

 jQuery('img#upload').imgAreaSelect({
 handles: true,
 keys: true,
 aspectRatio: xinit + ':' + yinit,
 show: true,
 x1: 0,
 y1: 0,
 x2: xinit,
 y2: yinit,
 maxHeight: &lt;?php echo 600; ?&gt;,
 maxWidth: &lt;?php echo 300; ?&gt;,
 onInit: function () {
 jQuery('#width').val(xinit);
 jQuery('#height').val(yinit);
 },
 onSelectChange: function(img, c) {
 jQuery('#x1').val(c.x1);
 jQuery('#y1').val(c.y1);
 jQuery('#width').val(c.width);
 jQuery('#height').val(c.height);
 }
 });
 });
 /* ]]&gt; */
 &lt;/script&gt;</pre>
<p>完成後，就讓他送出吧！</p>
<p><strong>第三步，儲存。</strong><br />
這部份就是單純的 PHP 呼叫，去更改摟！<br />
（依照應用面去儲存，弦也用在Slideshow所以是存到我儲存Slideshow資訊的變數內）</p>
<pre class="brush:php">$slides = get_option('slideshow');
 $slides = empty($slides) ? array() : $slides;

 if(intval($_GET['step']) != 2){
 if(intval($_GET['step']) == 3)
 {
 check_admin_referer('moho-slide-crop');
 if ( $_POST['oitar'] &gt; 1 ) {
 $_POST['x1'] = $_POST['x1'] * $_POST['oitar'];
 $_POST['y1'] = $_POST['y1'] * $_POST['oitar'];
 $_POST['width'] = $_POST['width'] * $_POST['oitar'];
 $_POST['height'] = $_POST['height'] * $_POST['oitar'];
 }

 $original = get_attached_file( $_POST['attachment_id'] );

 $cropped = wp_crop_image($_POST['attachment_id'], $_POST['x1'], $_POST['y1'], $_POST['width'], $_POST['height'], 600, 300);
 if ( is_wp_error( $cropped ) )
 wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );

 $cropped = apply_filters('wp_create_file_in_uploads', $cropped, $_POST['attachment_id']); // For replication

 $parent = get_post($_POST['attachment_id']);
 $parent_url = $parent-&gt;guid;
 $url = str_replace(basename($parent_url), basename($cropped), $parent_url);

 // Construct the object array
 $object = array(
 'ID' =&gt; $_POST['attachment_id'],
 'post_title' =&gt; basename($cropped),
 'post_content' =&gt; $url,
 'post_mime_type' =&gt; 'image/jpeg',
 'guid' =&gt; $url
 );

 // Update the attachment
 wp_insert_attachment($object, $cropped);
 wp_update_attachment_metadata( $_POST['attachment_id'], wp_generate_attachment_metadata( $_POST['attachment_id'], $cropped ) );

 if(isset($_POST['ss_id'])){
 $slide = &amp;$slides[$_POST['ss_id']];
 $slide['imgurl'] = $url;
 }else{
 $slide = array_pop($slides);
 $slide['imgurl'] = $url;
 array_push($slides, $slide);
 }
 update_option('slideshow', $slides);

 // cleanup
 $medium = str_replace(basename($original), 'midsize-'.basename($original), $original);
 @unlink( apply_filters( 'wp_delete_file', $medium ) );
 @unlink( apply_filters( 'wp_delete_file', $original ) );
 }
 call_step_1($slides);</pre>
<p><strong>補充說明：</strong><br />
在 WordPress 的 Custom Header 功能中，其設計為「頁面物件」<br />
整個產生都是由物件輔助，主要理由是因為 Step 3 結束後返回呼叫 Step 1 來避免多餘的換頁。</p>
<p>註：call_step_1() 是弦也產生預設頁面（第一步）的函式，這樣才會減少一次換頁。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-02-14/postid-1107/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[筆記] PHP 的單例設計模式</title>
		<link>http://blog.frost.tw/code/poston-2011-01-21/postid-959</link>
		<comments>http://blog.frost.tw/code/poston-2011-01-21/postid-959#comments</comments>
		<pubDate>Fri, 21 Jan 2011 13:30:56 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[Codeigniter]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[學習]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[筆記]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=959</guid>
		<description><![CDATA[前天在討論版上問了個問題，雖然得到了解答。 自己測試也得到了一個滿意的結果，不過我還是不解「不會重複消耗記憶體嗎？」的這個疑惑。 從我使用 Codeigniter 這個 Framework 一段時間後，我開始有了這個疑問。 而在得到新名詞「單例模式」時，我才頓悟。 （得到這名詞的方式有點小白，人家大大有點不耐煩了……不過我是真的第一次知道……） 弦也認為繁體中文章，阿育大大在色胚子部落格上的翻譯最為清楚好懂。 單例設計模式的用途 假使弦也沒有不幸的理解錯誤，那麼大概就是「避免重複產生實例」 依照弦也所蒐集到的資料，也就是如「資料庫物件」在每次使用時都會使用 new 產生一次，但非常消耗資源。 那麼最好的方法就是「限制產生」而且確保「只產生一次」來避免這個問題。 （弦也一直不解的其實就是Framework使用這麼多物件，記憶體是否會多次消耗。以此看來，這種方式就是對其做了處理。） 如何實做單例模式 就網路上的範例來看，大致至上都是如下的作法。 &#60;?php /** * @package 單例設計模式 * @author 蒼時弦也 */ class Core { private static $instance; //設置為靜態成員、私有 private function __construct() //將建構式設置為私有，避免外部調用 { &#8230; <a href="http://blog.frost.tw/code/poston-2011-01-21/postid-959">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前天在討論版上問了個問題，雖然得到了解答。<br />
自己測試也得到了一個滿意的結果，不過我還是不解「不會重複消耗記憶體嗎？」的這個疑惑。</p>
<p>從我使用 Codeigniter 這個 Framework 一段時間後，我開始有了這個疑問。<br />
而在得到新名詞「單例模式」時，我才頓悟。<br />
（得到這名詞的方式有點小白，人家大大有點不耐煩了……不過我是真的第一次知道……）<br />
<span id="more-959"></span><br />
弦也認為繁體中文章，<a href="http://blog.colorbase.tw/about" target="_blank">阿育</a>大大在<a href="http://blog.colorbase.tw/programming/625" target="_blank">色胚子</a>部落格上的翻譯最為清楚好懂。</p>
<p><strong>單例設計模式的用途</strong></p>
<p>假使弦也沒有不幸的理解錯誤，那麼大概就是「避免重複產生實例」<br />
依照弦也所蒐集到的資料，也就是如「資料庫物件」在每次使用時都會使用 new 產生一次，但非常消耗資源。<br />
那麼最好的方法就是「限制產生」而且確保「只產生一次」來避免這個問題。<br />
（弦也一直不解的其實就是Framework使用這麼多物件，記憶體是否會多次消耗。以此看來，這種方式就是對其做了處理。）</p>
<p><strong>如何實做單例模式</strong></p>
<p>就網路上的範例來看，大致至上都是如下的作法。</p>
<pre class="brush: php">&lt;?php
/**
 * @package 單例設計模式
 * @author 蒼時弦也
 */

class Core
{

  private static $instance; //設置為靜態成員、私有 

  private function __construct() //將建構式設置為私有，避免外部調用
  {
    //建構這個物件 Ex. 建立資料庫連接
  }

  public static function getInstance() //取得實例，物件會在這邊被建立
  {
    if(!self::$instance) //檢查時例是否存在（檢查方法蠻多種的，也有用 != NULL 檢查）
    {
      self::$instance = new Core(); //不存在時產生實例
    }
    return self::$instance; //傳回實例
  }

  //其他的處理在這
}

?&gt;
</pre>
<p>重點依照弦也理解，有下面幾項。</p>
<ul>
<li>建構子私有（避免外部調用，所以不會發生被產生第二次的情況）</li>
<li>有getInstance()之類的靜態方法（永遠用這個方法取得實例，因此實例被產生時永遠不會被產生第二次）</li>
<li>將 new Core() 改為 Core::getInstance() 調用（畢竟建構子私有無法再用 new 產生）</li>
</ul>
<p><strong>實做實驗</strong></p>
<p>弦也在學程式上真的就是「不打不相識」<br />
所以直接用 memory_get_usage() 這個函式來取得記憶體用量。<br />
並且比較兩個方法的記憶體消耗。</p>
<p>結果如下：</p>
<blockquote><p>Start Memory<br />
Memory used: 208</p>
<p>I&#8217;m traditional method!<br />
Memory used: 552</p>
<p>I&#8217;m traditional method!<br />
Memory used: 748</p>
<p>I&#8217;m traditional method!<br />
Memory used: 812</p>
<p>Free Memory<br />
Memory used: 812</p>
<p>Single Instance Method Start!</p>
<p>I&#8217;m single instance method!<br />
Memory used: 1128</p>
<p>Memory used: 1128</p>
<p>Memory used: 1128</p></blockquote>
<p>空行可不是失敗，而是弦也把輸出放在建構子裡面。</p>
<p>原始碼：</p>
<pre class="brush: php">&lt;?php
/**
 * @package 實例測試
 * @author 蒼時弦也
 */

class Traditional
{
 function __construct()
 {
 echo "I'm traditional method!";
 }

}

class SingleInstance
{
 private static $instance;

 private function __construct()
 {
 echo "I'm single instance method!";
 }

 public static function getInstance()
 {
 if(!self::$instance)
 {
 self::$instance = new SingleInstance();
 }
 return self::$instance;
 }

}

$start_used = memory_get_usage();

//Step 0 # Statr
echo 'Start Memory';
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 1 # Traditional Run 1
$obj = new Traditional();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 2 # Traditional Run 2 (Replace)
$obj = new Traditional();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 3 # Traditional Run 3 (New Varible)
$obj2 = new Traditional();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 4 # Free Memory
echo 'Free Memory';
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';

//Start Single Instance Method
echo 'Single Instance Method Start!&lt;br /&gt;&lt;br /&gt;';

//Step 5 # Single Instance Run 1
$obj = SingleInstance::getInstance();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 6 # Single Instance Run 2 (Replace)
$obj = SingleInstance::getInstance();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';
//Step 7 # Single Instance Run 3 (New Varible)
$obj2 = SingleInstance::getInstance();
echo '&lt;br /&gt;Memory used: '.(memory_get_usage() - $start_used).'&lt;br /&gt;&lt;br /&gt;';

?&gt;</pre>
<p>從原始碼可以看到，每次運行都輸出一次記憶體使用。<br />
直到開始使用單例模式後，記憶體就維持不變。</p>
<p>這在減少記憶體使用上，可以說一個大改進吧！<br />
（多虧了這個機會，弦也可是學到了很棒的知識呢！）</p>
<p>註：其實今天原本想偷懶不寫網誌的……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-01-21/postid-959/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP 中的 Function (函式) 數值傳遞測試（無解）</title>
		<link>http://blog.frost.tw/code/poston-2011-01-19/postid-953</link>
		<comments>http://blog.frost.tw/code/poston-2011-01-19/postid-953#comments</comments>
		<pubDate>Wed, 19 Jan 2011 11:29:34 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[bbPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=953</guid>
		<description><![CDATA[在 bbPress/WordPress 中，使用 Hook 製作插件時。 Filter 功能，如果直接使用 echo 輸出內容，那麼優先度在其之後者都無法顯示。 但是，如果將訊息處理後 return 回去，後面的函式又可以繼續處理。 但，似乎沒有使用 &#38; 去參照，到底是什麼情況呢？ 弦也決定親身測試，這個神覓得東西！ 測試 1 &#8211; 單純輸出 function do_func( $str ){ call_user_func_array('op2', array($str)); call_user_func_array('op3', array($str)); } function op1( $str ){ //Return to op2 return do_func($str); } function &#8230; <a href="http://blog.frost.tw/code/poston-2011-01-19/postid-953">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>在 bbPress/WordPress 中，使用 Hook 製作插件時。<br />
Filter 功能，如果直接使用 echo 輸出內容，那麼優先度在其之後者都無法顯示。</p>
<p>但是，如果將訊息處理後 return 回去，後面的函式又可以繼續處理。<br />
但，似乎沒有使用 &amp; 去參照，到底是什麼情況呢？</p>
<p>弦也決定親身測試，這個神覓得東西！<br />
<span id="more-953"></span><br />
測試 1 &#8211; 單純輸出</p>
<pre class="brush:php">
function do_func( $str ){
	call_user_func_array('op2', array($str));
	call_user_func_array('op3', array($str));
}

function op1( $str ){
	//Return to op2
	return do_func($str);
}

function op2( $str ){
	echo $str.'2';
}

function op3( $str ){
	echo $str.'3';
}

echo op1('hello');
</pre>
<p>結果：hello2hello3</p>
<p>測試2 &#8211; op2改為return</p>
<pre class="brush:php">
function op2( $str ){
	return $str.'2';
}
</pre>
<p>結果：hello3<br />
看起來，此時的 hello2 已經被 hello3 蓋過去了！<br />
再來測試 op3 也改為 return 時，是否會傳遞參數。</p>
<pre class="brush: php">
function op3( $str ){
	return $str.'3';
}
</pre>
<p>結果：空<br />
看起來，似乎是不會做任何傳遞動作的！</p>
<p>加上參照看看！</p>
<pre class="brush: php">
function do_func( &#038;$str ){
	call_user_func_array('op2', array($str));
	call_user_func_array('op3', array($str));
}
</pre>
<p>結果：空<br />
看起來也不行，也許哪裡漏了些東西！</p>
<p>打開 function.plugin-api.php 看看。</p>
<pre class="brush:php">
function apply_filters($tag, $value) {
	global $wp_filter, $merged_filters, $wp_current_filter;

	$args = array();
	$wp_current_filter[] = $tag;

	// Do 'all' actions first
	if ( isset($wp_filter['all']) ) {
		$args = func_get_args();
		_wp_call_all_hook($args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		array_pop($wp_current_filter);
		return $value;
	}

	// Sort
	if ( !isset( $merged_filters[ $tag ] ) ) {
		ksort($wp_filter[$tag]);
		$merged_filters[ $tag ] = true;
	}

	reset( $wp_filter[ $tag ] );

	if ( empty($args) )
		$args = func_get_args();

	do {
		foreach( (array) current($wp_filter[$tag]) as $the_ )
			if ( !is_null($the_['function']) ){
				$args[1] = $value;
				$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
			}

	} while ( next($wp_filter[$tag]) !== false );

	array_pop( $wp_current_filter );

	return $value;
}
</pre>
<p>看起來我們的 call_user_func_array() 也沒有問題，在 -Press 中也沒有使用 &#038; 做參照。<br />
對 op1 做調整看看。</p>
<pre class="brush:php">
function op1( $str ){
	//Return to op2
	echo $str;
	do_func($str);
}
</pre>
<p>結果：hello<br />
問題也不在 op1 身上，這倒是讓整個過程成了一個謎阿！</p>
<p>既然現在無解，就只好暫時放在一邊。<br />
也許哪天做測試時，會測出 -Press 為什麼可以傳遞數值的原因！<br />
（弦也自己寫的 Hook 也做不到，真是神奇！）</p>
<p>&#8212;<br />
17:49 補充</p>
<p>原來，一個一直有一個盲點。<br />
「程式的『循序』原則！」</p>
<p>因為 -Press 都用 Loop 去做，所以我們沒發現他不斷地 Replace $value 這個變數。<br />
正解：</p>
<pre class="brush: php">
function do_func( $str ){
	for($i = 2; $i < 3; $i++){
	$str = call_user_func_array('op2', array($str));
	$str = call_user_func_array('op3', array($str));

	return $str;
}
</pre>
<p>這樣一來，就能不斷串接了！<br />
（也可以避開一些用echo直接輸出的問題呢！）</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-01-19/postid-953/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用 Session 儲存 Object</title>
		<link>http://blog.frost.tw/code/poston-2011-01-18/postid-951</link>
		<comments>http://blog.frost.tw/code/poston-2011-01-18/postid-951#comments</comments>
		<pubDate>Tue, 18 Jan 2011 11:29:23 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Session]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[筆記]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=951</guid>
		<description><![CDATA[前幾天，我正在思考 PHP 快取的問題。 畢竟，每次都要運算，總會消耗一些程式運行的時間。 使用 Framework 或者大量的 Include 時，基本運作時間就會增加。 是否有辦法改善呢？ 此時我就把腦筋動到 SESSION 上面了！ 於是我就利用課餘時間 Google "PHP Store object in session" 的關鍵字。 找到了這篇介紹 Session 的文章： http://www.phpriot.com/articles/intro-php-sessions/8 看起來，我的腦筋動對地方了！ 既然可以儲存，那麼就來實做一下測試吧！ 簡易 User Object Store in Session 在這邊我們將一個用戶的資料都丟進 Session 裡面存取。 功能： 登入/登出 取得帳號、暱稱 下面弦也製造了兩個完全無意義的 &#8230; <a href="http://blog.frost.tw/code/poston-2011-01-18/postid-951">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前幾天，我正在思考 PHP 快取的問題。<br />
畢竟，每次都要運算，總會消耗一些程式運行的時間。<br />
使用 Framework 或者大量的 Include 時，基本運作時間就會增加。</p>
<p>是否有辦法改善呢？<br />
此時我就把腦筋動到 SESSION 上面了！<br />
<span id="more-951"></span><br />
於是我就利用課餘時間 Google "PHP Store object in session" 的關鍵字。<br />
找到了這篇介紹 Session 的文章：<br />
<a href="http://www.phpriot.com/articles/intro-php-sessions/8" target="_blank">http://www.phpriot.com/articles/intro-php-sessions/8</a></p>
<p>看起來，我的腦筋動對地方了！</p>
<p>既然可以儲存，那麼就來實做一下測試吧！<br />
簡易 User Object Store in Session</p>
<p>在這邊我們將一個用戶的資料都丟進 Session 裡面存取。<br />
功能：</p>
<ul>
<li>登入/登出</li>
<li>取得帳號、暱稱</li>
</ul>
<p>下面弦也製造了兩個完全無意義的 Class 來玩。<br />
（當作順便摸熟 OOP 的玩具了……）</p>
<p>user.php</p>
<pre class="brush: php">&lt;?php
//User Class

class User
{
 static private $username;
 static private $nickname;

 static public function login($username, $password)
 {
 if(self::checkUser($username) &amp;&amp; ($username == $password)){
 self::$username = $username;
 self::$nickname = '['.substr($username,0,4).']Nick'.intval(substr($username, 4));
 return true;
 }else{
 return false;    
 }
 }

 function checkUser($username){
 return ((intval(substr( $username, 4 ))^2)%2 == 0) &amp;&amp; $username != NULL;
 }
}

class CurrentUser extends User
{

 function __construct($username)
 {
 $this-&gt;username = $username;
 $this-&gt;nickname = '['.substr($username,0,4).']Nick'.intval(substr($username, 4));
 }

 function logout()
 {
 $this-&gt;username = NULL;    
 }

 function getNick()
 {
 return $this-&gt;nickname;    
 }

 function checkLogin()
 {
 return $this-&gt;checkUser($this-&gt;username);
 }

}</pre>
<p>index.php</p>
<pre class="brush: php">&lt;?php
//儲存物件於Session

include( 'user.php' );

session_start(); //Session Start

if($_POST['submit'] == 'Login'){
 if(User::login($_POST['username'], $_POST['password'])){
 session_register('user');
 $_SESSION['user'] = new CurrentUser($_POST['username']);
 header("Location:index.php");    
 }else{
 echo 'Login Failed!&lt;br /&gt;';    
 }
}

if(isset($_SESSION['user'])){
 $user = $_SESSION['user'];
 if($user-&gt;checkLogin())
 echo 'Current User is ', $user-&gt;getNick();
 else{
 $user-&gt;logout();
 session_unregister('user');
 header("Location:index.php");
 }

 //var_dump($_SESSION['user']-&gt;username);

}else{
 ?&gt;
 You aren't login!
 &lt;p&gt;
 &lt;form action="" method="post"&gt;
 Username: &lt;input name="username" type="text" /&gt;&lt;br /&gt;
 Password: &lt;input name="password" type="password" /&gt;&lt;br /&gt;
 &lt;input name="submit" type="submit" value="Login" /&gt;
 &lt;/form&gt;
 &lt;/p&gt;
 &lt;?php
}

?&gt;</pre>
<p>登入挺簡單的，只要輸入任意四個字+數字即可。<br />
這個數字需要為 (N^2)%2 == 0 的數字。</p>
<p>使用後就可以在有 Session 的情況下呼叫 CurrentUser 這個 Object 去做動作摟！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-01-18/postid-951/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Aotoki&#8217;s Codeigniter Day 1 &#8211; 安裝與產生第一個頁面</title>
		<link>http://blog.frost.tw/code/poston-2011-01-17/postid-949</link>
		<comments>http://blog.frost.tw/code/poston-2011-01-17/postid-949#comments</comments>
		<pubDate>Mon, 17 Jan 2011 11:05:24 +0000</pubDate>
		<dc:creator>蒼時弦や</dc:creator>
				<category><![CDATA[程式語言]]></category>
		<category><![CDATA[Codeigniter]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[架站]]></category>
		<category><![CDATA[程式]]></category>

		<guid isPermaLink="false">http://blog.frost.tw/?p=949</guid>
		<description><![CDATA[經過一天的嘗試，弦也大致上決定採用 Codeigniter 作為自己的夥伴。 雖然之後會嘗試自己開發一個 Framework , 不過功用還是有差。 （畢竟每種 Framework 都有其特性，弦也自己的大概是對其他人很不實用的……） 廢話不多說，我們先來下載 Codeigniter 以及安裝這個 Framework 吧！ （與其說是安裝，不如說是配置。） 我們選用的是 Codeigniter 1.7.3 版，直接在 下載頁面 點選下載連結即可。 完成後，第一件事就是解壓縮。 值後將 user_gulide 以外的檔案上傳到網站，或者你的測試伺服器。 註：弦也的測試伺服器是嵌入在Windows的coLinux(Debian)因此複製到 C:\coLinux\www\ci (弦也做的Link處理，以及要運作的目錄 接著，大家先將 system 裡面的 application 複製到根目錄，現在的目錄狀況大致上會如下。 ci (Root) - application - system &#8230; <a href="http://blog.frost.tw/code/poston-2011-01-17/postid-949">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>經過一天的嘗試，弦也大致上決定採用 Codeigniter 作為自己的夥伴。<br />
雖然之後會嘗試自己開發一個 Framework , 不過功用還是有差。<br />
（畢竟每種 Framework 都有其特性，弦也自己的大概是對其他人很不實用的……）</p>
<p>廢話不多說，我們先來<a href="http://www.codeigniter.org.tw/downloads" target="_blank">下載 Codeigniter</a> 以及安裝這個 Framework 吧！<br />
（與其說是安裝，不如說是配置。）<br />
<span id="more-949"></span><br />
我們選用的是 Codeigniter 1.7.3 版，直接在 <a href="http://www.codeigniter.org.tw/downloads" target="_blank">下載頁面</a> 點選下載連結即可。</p>
<p>完成後，第一件事就是解壓縮。<br />
值後將 user_gulide 以外的檔案上傳到網站，或者你的測試伺服器。<br />
註：弦也的測試伺服器是嵌入在Windows的coLinux(Debian)因此複製到 C:\coLinux\www\ci (弦也做的Link處理，以及要運作的目錄</p>
<p>接著，大家先將 system 裡面的 application 複製到根目錄，現在的目錄狀況大致上會如下。<br />
ci (Root)<br />
- application<br />
- system<br />
- index.php</p>
<p>如果你有 Rewrite Module 可以啟用，弦也建議新增一個 .htaccess 檔到根目錄來做 Rewrite 處理。<br />
.htaccess 檔內容：<br />
<code><br />
RewriteEngine On<br />
RewriteCond $1 !^(index\.php|images|robots\.txt)<br />
RewriteRule ^(.*)$ index.php/$1 [L]<br />
</code><br />
上面簡單的讓 index.php 這個 Front 去 Handler 整個 Framework 來處理。<br />
（MVC架構都是由 Router 去處理，而 index.php 就是啟動Router 的媒介。）</p>
<p>接下來，就是簡單編輯 application/config/config.php 這個設定擋了！<br />
我們將 base_url 這個設定值設定正確。<br />
（類似系統的路徑，之後會被Codeigniter調用。）</p>
<pre class="brush: php">/*
|--------------------------------------------------------------------------
| Base Site URL
|--------------------------------------------------------------------------
|
| URL to your CodeIgniter root. Typically this will be your base URL,
| WITH a trailing slash:
|
|	http://example.com/
|
*/
$config['base_url']	= "http://localhost/ci/"; //這是弦也本機測試的網址
</pre>
<p>那麼，打開你的 Codeigniter 就會看見預設的歡迎頁面了！</p>
<p>而這個歡迎頁面是由 application/views/welcome_message.php 產生的。<br />
其 Controller 則是 application/controllers/welcome.php</p>
<p>接下來，我們要自己產生一個頁面。<br />
但在此之前，我們需要理解一下 MVC 是什麼，還有套用 MVC 架構的 Framework 又是什麼。<br />
MVC 是 Model, View, Controller 三個字的縮寫。<br />
Model &#8211; 資料層（資料處理）<br />
View &#8211; 視圖層（畫面顯示）<br />
Controller &#8211; 控制層（程式處理）<br />
註：弦也印象不佳，沒有記錯應是如上。各位可以到 Wiki 上查詢正確的資訊。</p>
<p>簡單來說，我們把程式分成三個部份。<br />
資料處理（讀取資料、寫入資料等）、畫面顯示（產生畫面）、程式處理（登入、登出、計算等）</p>
<p>而 Framework 則是一些好用的功能集合，簡單說就是類似 WordPress 的 Plugin 功能，在需要時可以去呼叫來使用。<br />
使用 MVC 架構的 Framework 就是兩個合體拉（含糊不清</p>
<p>接下來我們說明一下 Router 這個東西。<br />
根據弦也使用 Codeigniter 和 ZendFramework 的經驗。</p>
<p>為了確立 MVC 這個架構不會亂掉，所以我們把每個頁面要呼叫的 Controller 用一個叫做 Router 的程式去分配。<br />
例如：/blog 分配給 BlogController.php 控制，把 /bbs 分配給 BbsController.php 去控制。<br />
如此一來，就不會混在一起。<br />
（當然也有例外情況，像是自己改寫 Router 的作法。）<br />
最最最簡單的去說他，那就是「發出指令的傢伙」<br />
最後就是 Controller 收到指令，去做他該做的事情。<br />
（就這樣，開始唬爛……）</p>
<p>嘛，既然現在有 Router 去幫你分派每個頁面該被呼叫的 Controller, 那麼就可以無視新增檔案了！<br />
我們直接到 application/controllers 裡面新增一個 hello.php 檔案吧！<br />
（新增這個檔案，只要寫好對應的 Controller 打開 /hello 的時候，就能產生頁面摟！）</p>
<p>hello.php 內容</p>
<pre class="brush:php">&lt;?php
class Hello extends Controller //檔名為 hello.php 時，類別名稱一定要是 Hello (首字大寫)
{
  functon __construct() //建構子，在 PHP5 之後才支援。
  {
    parent::Controller(); //確認父類別為 Controller
  }

  function index(){
    echo 'Hello World!';
  }
}
</pre>
<p>接著打開 http://localhost/ci/hello , 是否看到 Hello World! 字樣了呢？<br />
（上面是弦也的測試網址，各位要換成自己的喔！）</p>
<p>註：被 include 的檔案，結尾是不用 ?&gt; 的！</p>
<p>最後，我們再來學習一下 View 的使用。<br />
（Model 比較複雜，我們晚點再去玩他～）</p>
<p>到 application/views 下新增一個 hello_output.php<br />
hello_output.php 內容</p>
<pre class="brush: html, php">&lt;html&gt;
&lt;head&gt;Hello World!&lt;/head&gt;
&lt;body&gt;
Hello Codeigniter!
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>為了避免大家混淆，就用 hello_output.php 來和 hello.php 區分。</p>
<p>回到 application/controllers 編輯 hello.php 為下面的內容</p>
<pre class="brush:php">&lt;?php
class Hello extends Controller //檔名為 hello.php 時，類別名稱一定要是 Hello (首字大寫)
{
  functon __construct() //建構子，在 PHP5 之後才支援。
  {
    parent::Controller(); //確認父類別為 Controller
  }

  function index(){
    $this-&gt;load-&gt;view('hello_output'); //使用 Views 的 hello_output.php 檔案當作顯示
  }
}
</pre>
<p>那麼再次打開 /hello 是否出現 hello_output.php 的畫面了呢？</p>
<p>這就是，我們與 Codeigniter 的第一次接觸！<br />
註：Controller 的 index 方法是預設的首頁。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frost.tw/code/poston-2011-01-17/postid-949/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

