<?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.wabow.com/archives/category/it/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.wabow.com</link>
	<description>Wabow Information Inc. Blog</description>
	<lastBuildDate>Fri, 20 Jan 2012 09:19:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>[CSS]關於網頁中使用CSS中使用嵌入字型</title>
		<link>http://blog.wabow.com/archives/2470</link>
		<comments>http://blog.wabow.com/archives/2470#comments</comments>
		<pubDate>Fri, 20 Jan 2012 09:19:27 +0000</pubDate>
		<dc:creator>Doris</dc:creator>
				<category><![CDATA[工作雜談]]></category>
		<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2470</guid>
		<description><![CDATA[一般來說在設計網站的時候，都是使用預設的系統字型來設計。但如果網站上英文、數字不使用一般系統原有字型。這樣就變成必需要使用另外嵌入的字型了。例如國外的一個服飾網站A&#38;F的網站(如下圖)： 這些字可不是圖片，真的是CSS嵌入字型完成的作品....而且IE6 ~ 9、Firefox、Safari、Chrome、Opera都可以正常顯示。但要滿足這麼多瀏覽器的情況，A&#38;F是怎麼樣做到的呢？ 正確的答案就是，使用@font-face！那@font-face要怎麼用呢？請看範例： 1. 先在css中定義要使用的字型名稱以及字型檔放置的位置 我們在A&#38;F的CSS原始碼中查看到其中一個字型的@font-face設定如下： @font-face{ font-family:'Trade Gothic Bold'; /** 這個是設定字型的名稱 **/ src:url('/anf/font/tradegothic-bold-webfont.eot'); /** 設定IE使用的EOT字型檔位置 **/ src:local('☺'),url('/anf/font/tradegothic-bold-webfont.woff') format('woff'),url('/anf/font/tradegothic-bold-webfont.ttf') format('truetype'),url('/anf/font/tradegothic-bold-webfont.svg#webfontmlgY0et7') format('svg'); /** 設定firefox、chrome...等使用的字型檔放置的地方 **/ font-weight:normal;font-style:normal; /** 其餘的css設定 **/ } 我們可以發現，其實在使用@font-face的時候，「好像」需要很多不同類型的字型格式檔....但是，不要懷疑。因為各家瀏覽器在支援的字型格式不同的情況下，所以造成了必須要將希望正常顯示字型的瀏覽器都要設定的情況。 所以，要使用的時候，需要先將@font-face照前面的程式碼先設定好後，再用一般使用CSS設定字型的方式套用，如下方範例： .changeType{ font-size: 30px; font-family: "Trade Gothic Bold"; } 接下來會看到字型會被套上的樣子...(此字型是套另一個worldwideweb字型) 2. 那些瀏覽器支援什麼樣的字型檔？ 基本上，因為常見到的瀏覽器有幾種：IE系列、Firefox、Safari、Chrome。基本上，這幾種瀏覽器都是需要正常顯示出來。初步測試後，支援字型檔的格式如下： * IE6, IE7, IE8, IE9： 支援EOT字型檔。 * Firefox：支援otf以及ttf、woff * Safari：支援svg、otf [...]]]></description>
			<content:encoded><![CDATA[<p>一般來說在設計網站的時候，都是使用預設的系統字型來設計。但如果網站上英文、數字不使用一般系統原有字型。這樣就變成必需要使用另外嵌入的字型了。例如國外的一個服飾網站<a href="http://www.abercrombie.com">A&amp;F</a>的網站(如下圖)：</p>
<p><a href="http://blog.wabow.com/archives/2470/anfscreenshot" rel="attachment wp-att-2472"><img class="alignnone size-large wp-image-2472" src="http://blog.wabow.com/wp-content/uploads/2012/01/anfscreenshot-500x340.jpg" alt="" width="500" height="340" /></a></p>
<p>這些字可不是圖片，真的是CSS嵌入字型完成的作品....而且IE6 ~ 9、Firefox、Safari、Chrome、Opera都可以正常顯示。但要滿足這麼多瀏覽器的情況，<a href="http://www.abercrombie.com">A&amp;F</a>是怎麼樣做到的呢？</p>
<p><span id="more-2470"></span></p>
<p>正確的答案就是，使用<b>@font-face</b>！那<b>@font-face</b>要怎麼用呢？請看範例：<br />
<br /></p>
<h4>1. 先在css中定義要使用的字型名稱以及字型檔放置的位置</h4>
<p>我們在A&amp;F的CSS原始碼中查看到其中一個字型的<code>@font-face</code>設定如下：</p>
<div class="wp_syntax">
<div class="code">
@font-face{</p>
<p>    font-family:'Trade Gothic Bold'; /** 這個是設定字型的名稱 **/</p>
<p>    src:url('/anf/font/tradegothic-bold-webfont.eot'); /** 設定IE使用的EOT字型檔位置 **/</p>
<p>    src:local('☺'),url('/anf/font/tradegothic-bold-webfont.woff') format('woff'),url('/anf/font/tradegothic-bold-webfont.ttf')<br />
format('truetype'),url('/anf/font/tradegothic-bold-webfont.svg#webfontmlgY0et7') format('svg'); /** 設定firefox、chrome...等使用的字型檔放置的地方 **/</p>
<p>    font-weight:normal;font-style:normal; /** 其餘的css設定 **/</p>
<p>}
</p></div>
</div>
<p>我們可以發現，其實在使用<b>@font-face</b>的時候，「好像」需要很多不同類型的字型格式檔....但是，不要懷疑。因為各家瀏覽器在支援的字型格式不同的情況下，所以造成了必須要將希望正常顯示字型的瀏覽器都要設定的情況。<br />
所以，要使用的時候，需要先將<b>@font-face</b>照前面的程式碼先設定好後，再用一般使用CSS設定字型的方式套用，如下方範例：</p>
<div class="wp_syntax">
<div class="code">
.changeType{</p>
<p>    font-size: 30px;</p>
<p>    font-family: "Trade Gothic Bold";<br />
}
</p></div>
</div>
<p>接下來會看到字型會被套上的樣子...(此字型是套另一個worldwideweb字型)<br />
<a href="http://blog.wabow.com/archives/2470/ie8" rel="attachment wp-att-2471"><img src="http://blog.wabow.com/wp-content/uploads/2012/01/ie8-500x215.jpg" alt="" width="500" height="215" class="alignnone size-large wp-image-2471" /></a></p>
<p><br /></p>
<h4>2. 那些瀏覽器支援什麼樣的字型檔？</h4>
<p>基本上，因為常見到的瀏覽器有幾種：IE系列、Firefox、Safari、Chrome。基本上，這幾種瀏覽器都是需要正常顯示出來。初步測試後，支援字型檔的格式如下：</p>
<p>* IE6, IE7, IE8, IE9： 支援EOT字型檔。<br />
* Firefox：支援otf以及ttf、woff<br />
* Safari：支援svg、otf<br />
* Chrome (Google 瀏覽器)：支援svg、otf</p>
<p><br /></p>
<h4>3. 這幾個英文是什麼意思？</h4>
<p>* <strong>EOT(Embedded OpenType)</strong>： 由微軟制定並於2008年1月提交至W3C的字型規格。因為本篇不是在介紹字型格式，所以詳情可以看<a href="http://www.w3.org/Submission/2008/SUBM-EOT-20080305/" target="_blank">這邊</a>了解格式的內容。</p>
<p>* <strong>OTF(OpenType)</strong>：也是由微軟一開始制定，後來adobe也加入共同發展。<a href="http://www.microsoft.com/typography/otspec/" target="_blank">字型規格</a></p>
<p>* <strong>TTF(TrueType)</strong>：早期為了對抗Adobe的Type1 Postcript字體而由Apple、微軟共同開發的一種字體標準。<a href="http://developer.apple.com/fonts/TTRefMan/index.html" target="_blank">字型規格</a></p>
<p>* <strong>WOFF(Web Open Font Format)</strong>：2010年由Mozzila基金會、Opera、微軟一起送出的Web開放字型格式。</p>
<p>* <strong>SVG(Scalable Vector Graphics)</strong>：這不是一種字型檔，而是基於XML的一種製造二維向量圖形的格式。由<a href="http://www.w3.org/" target="_blank">W3C</a>制定，是一種開放標準。頁面請見<a href="http://www.w3.org/Graphics/SVG/" target="_blank">此處</a></p>
<p>基本上只要特別注意提供支援的格式，其實你也做的到不使用系統預設字型來設計網頁！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2470/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python 環境建置</title>
		<link>http://blog.wabow.com/archives/2410</link>
		<comments>http://blog.wabow.com/archives/2410#comments</comments>
		<pubDate>Mon, 19 Dec 2011 07:35:15 +0000</pubDate>
		<dc:creator>Doris</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2410</guid>
		<description><![CDATA[這次特殊需要，所以建立python環境做一些工作上所需的處理。其實在建立python基本上環境連結mysql不會太困難... 使用的環境為windows 32bit 以及python 2.7版... 一、下載安裝python: 請先到 http://python.org/getit/ 下載windows的installer(目前是使用python 2.7版) &#160; 二、一直下一步安裝: 預設安裝會將python2.7安裝在 c:\Python27 的資料夾之中。在這個時候，windows上直接開始Dos模式後直接下 c:\python &#160; 會出現錯誤，因為這個時候系統並沒有將python認成是內部指令。 &#160; 三、設定環境變數: 在系統 / 進階 / 環境變數之中，加入以下變數設定： &#160; PATH = C:\Python27 &#160; 接下來重開一次Dos模式重新再下一次python指令後，應該會進入python的指令模式。這時候退出請下： &#160; exit() &#160; 基本的python環境就完成了。 &#160; 四、安裝套件工具easy_install 先到http://pypi.python.org/pypi/setuptools#files下載相對python版本的工具。因為之前筆者安裝的是python 2.7，所以在這邊安裝了2.7版本的setuptools-0.6c11.win32-py2.7.exe檔。 下載好後，直接點開一直按下一步安裝。除非預設的Python27的資料夾有變動，否則直接下一步安裝就可以完成了。當安裝完畢後，會在C:\Python27\Scripts這個資料夾下發現有easy_install的程式可以執行。 &#160; 五、將easy_install加到環境變數之中 因為安裝後還是不能直接在dos環境下直接下指令，所以，就手動把環境變數加進去。 &#160; PATH = C:\Python27\Scripts &#160; 六、安裝MySQLdb for Python: 先到這個網址: http://www.codegood.com/archives/129下載讓python 2.7使用的檔案。下載好後，一樣直接點二下執行安裝。一樣一直按「下一步」安裝，就會安裝在預設的資料夾C:\Python27之中。 (本文為32bit的安裝方式。64bit會需要更改機碼。) [...]]]></description>
			<content:encoded><![CDATA[<p>這次特殊需要，所以建立python環境做一些工作上所需的處理。其實在建立python基本上環境連結mysql不會太困難...<br />
使用的環境為windows 32bit 以及python 2.7版...<br />
<span id="more-2410"></span></p>
<h3>一、下載安裝python:</h3>
<p>請先到<a href="http://python.org/getit/"><code><code> http://python.org/getit/</code></code></a> 下載windows的installer(目前是使用python 2.7版)<br />
&nbsp;</p>
<h3>二、一直下一步安裝:</h3>
<p>預設安裝會將python2.7安裝在 <code>c:\Python27</code> 的資料夾之中。在這個時候，windows上直接開始Dos模式後直接下</p>
<div class="wp_syntax">
<div class="code">
<pre style="font-family: monospace">c:\python</pre>
</div>
</div>
<p>&nbsp;</p>
<p>會出現錯誤，因為這個時候系統並沒有將python認成是內部指令。<br />
&nbsp;</p>
<h3>三、設定環境變數:</h3>
<p>在<code>系統 / 進階 / 環境變數</code>之中，加入以下變數設定：<br />
&nbsp;</p>
<div class="wp_syntax">
<div class="code">
<pre style="font-family: monospace">PATH = C:\Python27</pre>
</div>
</div>
<p>&nbsp;<br />
接下來重開一次<code>Dos模式</code>重新再下一次python指令後，應該會進入python的指令模式。這時候退出請下：<br />
&nbsp;</p>
<div class="wp_syntax">
<div class="code">
<pre style="font-family: monospace">exit()</pre>
</div>
</div>
<p>&nbsp;<br />
基本的python環境就完成了。<br />
&nbsp;</p>
<h3>四、安裝套件工具easy_install</h3>
<p>先到<a href="http://pypi.python.org/pypi/setuptools#files"><code>http://pypi.python.org/pypi/setuptools#files</code></a>下載相對python版本的工具。因為之前筆者安裝的是python 2.7，所以在這邊安裝了2.7版本的<code>setuptools-0.6c11.win32-py2.7.exe</code>檔。 下載好後，直接點開一直按下一步安裝。除非預設的Python27的資料夾有變動，否則直接下一步安裝就可以完成了。當安裝完畢後，會在<code>C:\Python27\Scripts</code>這個資料夾下發現有<code>easy_install</code>的程式可以執行。<br />
&nbsp;</p>
<h3>五、將easy_install加到環境變數之中</h3>
<p>因為安裝後還是不能直接在dos環境下直接下指令，所以，就手動把環境變數加進去。<br />
&nbsp;</p>
<div class="wp_syntax">
<div class="code">
<pre style="font-family: monospace">PATH = C:\Python27\Scripts</pre>
</div>
</div>
<p>&nbsp;</p>
<h3>六、安裝MySQLdb for Python:</h3>
<p>先到這個網址: <a href="http://www.codegood.com/archives/129">http://www.codegood.com/archives/129</a>下載讓python 2.7使用的檔案。下載好後，一樣直接點二下執行安裝。一樣一直按「下一步」安裝，就會安裝在預設的資料夾<code>C:\Python27</code>之中。 (本文為32bit的安裝方式。64bit會需要更改機碼。)</p>
<p>這樣就完成了。</p>
<p>文章轉自：<a href="http://blog.walile.info/blog/2011/12/19/install-python-and-mysqldb-on-windows/" title="在windows環境中設定python以及MySQLdb">在windows環境中設定python以及MySQLdb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2410/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework Testing 入門 - 測試環境建置篇</title>
		<link>http://blog.wabow.com/archives/2345</link>
		<comments>http://blog.wabow.com/archives/2345#comments</comments>
		<pubDate>Fri, 21 May 2010 10:51:28 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2345</guid>
		<description><![CDATA[本文轉自：Zend Framework Testing 入門 - 測試環境建置篇 自 Zend Framework 1.6 之後就提供了 Zend_Test 這個套件，協助我們為 Zend Framework 的 MVC 做單元測試。然而當時也許是因為大家對 Zend Framework 的新架構還不熟悉，加上 Zend_Test 套件有許多小地方還不是很完善，因此就很少有人利用它來做測試。 而到了 Zend Framework 1.8 版之後， Zend_Test 便修正了許多缺點；而且也因為 Zend_Application 套件的引入，讓 Zend_Test 在 Controller 上的測試更加方便，也使得網路上許多高手開始為它編寫教學。 不過官方的文件並沒有特別告訴我們怎麼去建構 Zend Framework Testing 的環境，所以以下我以 Zend Framework 1.10 再加上 PHPUnit 3.4 為例，帶領大家進入 Zend Framework Testing 的世界。 準備 Zend Framework [...]]]></description>
			<content:encoded><![CDATA[<p>本文轉自：<a href="http://www.jaceju.net/blog/?p=1152">Zend Framework Testing 入門 - 測試環境建置篇</a></p>
<p>自 Zend Framework 1.6 之後就提供了 Zend_Test 這個套件，協助我們為 Zend Framework 的 MVC 做單元測試。然而當時也許是因為大家對 Zend Framework 的新架構還不熟悉，加上 Zend_Test 套件有許多小地方還不是很完善，因此就很少有人利用它來做測試。</p>
<p>而到了 Zend Framework 1.8 版之後， Zend_Test 便修正了許多缺點；而且也因為 Zend_Application 套件的引入，讓 Zend_Test 在 Controller 上的測試更加方便，也使得網路上許多高手開始為它編寫教學。</p>
<p>不過官方的文件並沒有特別告訴我們怎麼去建構 Zend Framework Testing 的環境，所以以下我以 Zend Framework 1.10 再加上 PHPUnit 3.4 為例，帶領大家進入 Zend Framework Testing 的世界。</p>
<p><span id="more-2345"></span></p>
<h2>準備 Zend Framework 專案</h2>
<p>要進行測試前，我們得先要有個 Zend Framework 專案。假設這個專案名稱叫 unittest ，原始檔位於 D:\WEB\zf\unittest 上，我們用 Zend Framework 提供的 Zend_Tool工具來建立它：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">zf create project unittest</pre></div></div>

<p>然後我們切換到該專案目錄下：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #b1b100; font-weight: bold;">cd</span> unittest</pre></div></div>

<p class="note">註：雖然我是以 Win32 為主要環境，但 Linux 上的操作步驟也是雷同。</p>
<p>由於我個人偏好搬動整個目錄就可以移植專案的模式，因此我就不採用 Zend Framework 原本將 index.php 放在 public 目錄下的架構；以下動作的目的就是把 index.php 從 public 目錄移出來。</p>
<p>首先先把 D:\WEB\zf\unittest\public\index.php 和 D:\WEB\zf\unittest\public\.htaccess 複製到 D:\WEB\zf\unittest 下，然後修改 D:\WEB\zf\unittest\.zfproject.xml ，把上方紅框處的 index.php 和 .htaccess 的 XML tag 複製一份到下方的紅框處：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/zfproject_xml.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/zfproject_xml.png" alt="修改 .zfproject.xml" /></a></p>
<p>接下來要修改 D:\WEB\zf\unittest\index.php 中 application 目錄的相對位置；找到：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>改為：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>然後我們要在 D:\WEB\zf\unittest\.htaccess 加入當前環境的常數，也就是在它的最上面一行加入：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">SetEnv APPLICATION_ENV development</pre></div></div>

<p>原來的 D:\WEB\zf\unittest\public\index.php 則用來阻擋使用者瀏覽 public 目錄，所以我們把它改成：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP/1.1 403 Forbidden'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>而原來的 D:\WEB\zf\unittest\public\.htaccess 則是將 Rewrite Engine 關閉，讓外界可以直接存取：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">RewriteEngine Off</pre></div></div>

<p>這樣就準備好我們的專案了。</p>
<h2>在 NetBeans 中加入專案</h2>
<p>NetBeans 近來對 PHP 的支援變得非常強大，讓我一用就愛上它。到  6.8 版為止， NetBeans 還沒有正式支援 Zend Framework ，不過這並不影響我們用它來開發以 Zend Framework 為架構的專案。</p>
<p> 而這裡會提到 NetBeans ，主要是因為它支援了 PHPUnit ！而且還有圖形化介面；這使得我們在對 PHP 專案進行單元測試時更加便利！</p>
<p>回到剛剛我們建立的 Zend Framework 專案，我們可以在 NetBeans 裡加入一個現成的 PHP 專案。在工具列中，選擇 File &gt; New Project... 後，會出現以下視窗：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/new_php_project.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/new_php_project.png" alt="建立 NetBeans 專案" /></a></p>
<p>然後要選擇現存專案的位置：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/location.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/location.png" alt="選擇專案位置" /></a></p>
<p>最後設定專案執行時的設置：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/final.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/final.png" alt="完成專案其它設定" /></a></p>
<p>這樣一來我們就可以在 NetBeans 裡開發 Zend Framework 的專案了。</p>
<h2>Zend_Test 基礎</h2>
<p>Zend_Test 主要是基於 PHPUnit 這個 PHP 界公認最完善的自動化測試套件所開發的，所以不論是在設置環境或是在撰寫測試上，其實都是以 PHPUnit 的架構去完成。</p>
<p>為了避免本文內容過於冗長，這裡我已經先行設定好 PHPUnit 的執行環境；因此在繼續以下的步驟前，請大家先確認自己是否可以正確執行 PHPUnit 。</p>
<p>在 Zend Framework 為我們們準備好的專案目錄架構中，已經事先建立了 tests 這個供我們放置測試的目錄，所以現在我們可以先試試看用 PHPUnit 來執行我們的測試。假設我們目前的工作路徑是 D:\WEB\zf\unittest\ ，我們要先切換到 tests 目錄下：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #b1b100; font-weight: bold;">cd</span> tests</pre></div></div>

<p>然後用 PHPUnit 提供的 Command Line Interface (CLI) 工具 phpunit 來執行測試：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">phpunit .</pre></div></div>

<p>我們會發現執行的結果出現了以下錯誤：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">PHPUnit_Framework_Exception: Could not load &quot;D:\WEB\zf\unittest\tests\phpunit.xml&quot;.</pre></div></div>

<p>原來， phpunit 這個工具在我們對一個目錄進行測試時，會自動去剖析該目錄下的 phpunit.xml 內容；而 phpunit.xml 在 Zend_Tool 產生之後，並沒有任何內容，所以就使得 PHPUnit 丟出了一個異常。</p>
<p>所以這裡我們先簡單將它變成一個正確的 XML 檔案，在 D:\WEB\zf\unittest\tests\phpunit.xml 中我們加入：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phpunit<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/phpunit<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>然後在 Command Line 環境下再跑一次測試，結果如下：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/phpunit_cli.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/phpunit_cli.png" alt="執行 phpunit" /></a></p>
<p>這表示 PHPUnit 認得我們的測試環境啦！</p>
<h2>建立測試</h2>
<p>其實上面也只是讓 phpunit 能在我們的專案上啟用而已，但我們的測試主角根本還沒出現，所以接下來我們要開始來建立測試了。</p>
<p>Zend_Tool 建立出來的專案架構，其實有個預設的前置名稱，叫做 Application ；這個 Application 之後都做為專案中 Model 的前置名稱。一般來說，我都會將它改為像是 MyApp 或是 Shop 等等諸如此類符合目前專案性質的名稱。 Zend_Tool 也提供我們修改這個前置名稱的機制：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">zf change application.class-name-prefix MyApp</pre></div></div>

<p>執行結果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Note: the name provided &quot;MyApp&quot; was altered to &quot;MyApp_&quot; for correctness.
Note: All existing models will need to be altered to this new namespace by hand
application.ini updated with new appnamespace MyApp_
Updating project profile 'D:\WEB\zf\unittest/.zfproject.xml'</pre></div></div>

<p>要注意的是，如果在修改前就已經存在的 Model ，它們的前置名稱就要手動改成新的。</p>
<h3>建立第一個 Model</h3>
<p>接著我們建立第一個 Model Class ：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">zf create model MyClass1</pre></div></div>

<p>執行結果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Creating a model at D:\WEB\zf\unittest/application/models/MyClass1.php
Updating project profile 'D:\WEB\zf\unittest/.zfproject.xml'</pre></div></div>

<p>在 D:\WEB\zf\unittest/application/models/MyClass1.php 中就是 MyClass1 的內容：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MyApp_Model_MyClass1
<span style="color: #009900;">&#123;</span>
&nbsp;
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>當然這個檔案目前只有簡單的類別定義而已，其他就是要靠我們自己手動完成。不過由於我們的重點是測試，所以這裡我們就不管 MyClass1 的內容。</p>
<h3>用 NetBeans 產生 Test Case</h3>
<p>前面提到 NetBeans 支援 PHPUnit ，因此這裡我們就直接試著用它來幫我們產生測試檔案。切換到專案目錄的「 Source Files/application/models 」下，在 MyClass1.php 上按下右鍵選擇「工具 / Create PHPUnit tests 」，我們就可以建立針對 MyClass1 類別的 Test Case ：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/create_phpunit_tests.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/create_phpunit_tests.png" alt="產生 Model Test Case" /></a></p>
<p>但因為 NetBeans 還不知道測試目錄的所在位置，因此它會提示我們輸入測試目錄；在這裡，我們當然就是選擇 D:\WEB\zf\unittest\tests ：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/select_test_dir.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/select_test_dir.png" alt="選擇測試目錄" /></a></p>
<p>在按下確定之後， NetBeans 就會自動打開產生好的 Test Case 檔案。在本例中，它的位置就是在 D:\WEB\zf\unittest\tests\application\models\MyApp_Model_MyClass1Test.php 。</p>
<p>另外 NetBeans 也會把 tests 從原來的 Source Files 中獨立成 Test Files 目錄結構，但別忘了它實際的位置還是在 D:\WEB\zf\unittest\ 下。</p>
<h3>目錄結構對應</h3>
<p>繼續下個步驟之前，我們先來整個專案的目錄結構：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">unittest
 |--application
 |   |--models
 |       |--MyClass1.php
 |--library
 |--docs
 |--public
 |--tests
 |   |--application
 |       |--models
 |           |--MyApp_Model_MyClass1Test.php
 |   |--library
 |   |--phpunit.xml
 |--.zfproject.xml
 |--.htaccess
 |--index.php</pre></div></div>

<p>從上面的架構圖可以看到，在這個 tests 目錄下的 application 及 library ，就是對應著我們的專案目錄下的 application 及 library 。換句話說，我們在專案目錄下的 application/models 所建立的 Model Class ，它們的測試程式就可以放在 tests/application/models 下，其他以此類推。</p>
<h3>執行測試類別</h3>
<p>在我們建立好 MyApp_Model_MyClass1Test 這個測試類別後，就可以在上面撰寫測試案例了。這裡我們先簡單加入一個空的測試案例，即 testMethod1 方法：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// ... 略 ...</span>
<span style="color: #000000; font-weight: bold;">class</span> MyApp_Model_MyClass1Test <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Framework_TestCase
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testMethod1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>接著就可以執行測試了。</p>
<p>這裡雖然我們可以用 phpunit 來執行測試，不過 NetBeans 也可以幫我們代勞。我們可以在 NetBeans 的 Project 視窗中，對 unittest 專案名稱按下滑鼠右鍵，執行 Test 指令 (或直接按下 Alt + F6 ) ，這樣就會開始執行測試了。</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/run_project_test.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/run_project_test.png" alt="執行專案測試" /></a></p>
<p>完成測試後，就會出現下圖中的 Test Results 視窗。</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/netbeans_test.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/netbeans_test.png" alt="完成測試的畫面" /></a></p>
<p>這看起來是不是比先前的 Command Line 輸出結果好多了呢？</p>
<h2>測試環境的自動載入</h2>
<p>在測試時，其實我希望要測試用的類別能被自動載入，而不需要加入一堆的 require_once 。以往我在舊專案的做法是在每個測試案例之前，引用一個 bootstrap.php 檔，內容如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APP_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../app/'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/lib'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/base'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/mod/common/models'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">get_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> autoload<span style="color: #009900;">&#40;</span><span style="color: #000088;">$className</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$className</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'_'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$className</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$className</span>.php&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">spl_autoload_register</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'autoload'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>而在新架構中， Zend_Tool 很貼心地為我們產生好了這個檔案，也就是 D:\WEB\zf\unittest\tests\application\bootstrap.php 。</p>
<p class="note">註：不過 D:\WEB\zf\unittest\tests\application\bootstrap.php 裡面的內容是空的，我們得自己把它加入。</p>
<p>但是每次都要在測試類別檔載入這個 bootstraop.php 也是相當麻煩，還好 PHPUnit 讓我們可以在 phpunit.xml 中去加入對 bootstraop.php 的自動引用。接下來請將 D:\WEB\zf\unittest\tests\phpunit.xml 的內容改為：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phpunit</span> <span style="color: #000066;">bootstrap</span>=<span style="color: #ff0000;">&quot;./application/bootstrap.php&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>這麼一來，當我們執行 phpunit 時，就會自動引入 bootstraop.php 了。而這裡要注意的是， ./application/bootstrap.php 這個路徑是相對於 phpunit.xml 的，其他非絕對路徑的設定也是。</p>
<p>不過上面的  bootstraop.php 寫法在新的 Zend Framework 架構中就不適用了，因為它的自動載入只能應付類別名稱為 Xxx_Yyy_Zzz 並對應到檔名為 Xxx/Yyy/Zzz.php 的模式；而新架構中的 Model 則是位於 application/models 之下，也就是說我們的 MyApp_Model_MyClass1 這個類別的實際位置是 D:\WEB\zf\unittest\application\models\MyApp_Model_MyClass1.php ，因此我們得想辦法讓 bootstrap.php 能自動載入新架構的 Model Class 。</p>
<p>還好 Zend_Loader 提供了 Zend_Loader_Autoloader_Resource 這個套件，來幫我們載入 Zend Framework MVC 架構下的 Model Class 。所以我們的 bootstrap.php 就可以改成：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">error_reporting</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">E_ALL</span> <span style="color: #339933;">|</span> <span style="color: #009900; font-weight: bold;">E_STRICT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">date_default_timezone_set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Asia/Taipei'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'testing'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../../application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_CONFIG'</span><span style="color: #339933;">,</span> APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/application.ini'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../library'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../tests'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">get_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Loader/Autoloader.php'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$autoloader</span> <span style="color: #339933;">=</span> Zend_Loader_Autoloader<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$resourceLoader</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Loader_Autoloader_Resource<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'basePath'</span>      <span style="color: #339933;">=&gt;</span> APPLICATION_PATH<span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'namespace'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'MyApp'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'resourceTypes'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'model'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'path'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'models/'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'namespace'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Model'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$autoloader</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pushAutoloader</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$resourceLoader</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p class="note">註： Zend_Loader_Autoloader_Resource 的詳細用法請參考官方手冊 <a href="http://zendframework.com/manual/en/zend.loader.autoloader-resource.html">Resource Autoloaders</a> 一節的說明。</p>
<p>現在我們可以試著把 MyApp_Model_MyClass1Test.php 中的 require_once 敘述移除，試試看 phpunit 會不會自動載入。</p>
<p>不過特別要注意的是， bootstrap.php 只會在 phpunit.xml 被載入時自動被引用，因此我們就一定要透過 phpunit . 這樣的方式來執行測試，不然就會發生找不到 Model Class 檔案的狀況。如果我們只想單獨執行某個測試類別時 (例如 MyApp_Model_MyClass1Test ) ，就必須改用以下的方式執行：  (假設當前工作目錄是在 D:\WEB\zf\unittest\tests ) </p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">phpunit application\models\MyApp_Model_MyClass1Test<span style="color: #339933;">.</span>php <span style="color: #339933;">--</span>configuration <span style="color: #339933;">./</span>phpunit<span style="color: #339933;">.</span>xml</pre></div></div>

<p>而在 NetBeans 中，我們可以在 Project 視窗的 Test Files 上按下滑鼠右鍵選擇 Properties ，就會出現以下視窗：</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/phpunit_config.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/phpunit_config.png" alt="NetBeans 中的 PHPUnit 設定" /></a></p>
<p>然後我們再指定 phpunit.xml 的位置，這樣就算只對單一的 Model 進行測試， NetBeans 也會自動幫我們載入 phpunit.xml 了。</p>
<h2>加入更多測試</h2>
<p>一個專案裡要測試的 Model 當然不可能只有一個，接著我們再加入新的 Model 。在 D:\WEB\zf\unittest 之下，我們執行：</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">zf create model MyClass2</pre></div></div>

<p>然後再透過 NetBeans 的 Create PHPUnit tests ，幫它建立一個測試類別 MyApp_Model_MyClass2Test 。當然也別忘了幫這個測試類別加入測試案例，以免執行測試時會出現沒有測試案例的警告。</p>
<p>不是只有 Model 可以被測試，在 Zend_Test 裡也提供了測試 Controller 的方法；方法很簡單，以預設的 IndexController 為例，我們一樣也是在 NetBeans 的 Project 視窗中，對 unittest/application/controllers/IndexController.php 執行 Create PHPUnit tests 就可以了。</p>
<p>但是這樣卻有可能出現以下的錯誤訊息，而無法成功建立 IndexController 的測試類別。</p>
<p class="image"><a href="http://www.jaceju.net/resources/zend_test_with_netbeans/create_test_error.png"><img src="http://www.jaceju.net/resources/zend_test_with_netbeans/create_test_error.png" alt="建立測試失敗" /></a></p>
<p>而查看輸出視窗 (Ctrl + 4) ，實際的錯誤訊息是：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Fatal error: Class 'Zend_Controller_Action' not found in D:\WEB\zf\unittest\application\controllers\IndexController.php on line 3</pre></div></div>

<p>這是因為 NetBeans 其實是透過 phpunit --skeleton-test 這個指令來幫助我們建立測試類別，而 --skeleton-test 會利用 PHP 5 的 Reflection 機制幫我們找出類別裡的方法；但 Reflection 也會需要相關引用到的類別的定義 (這裡就是 Zend_Controller_Action ) ，因此在沒有事先定義好的狀況下， phpunit 就會回報錯誤了。</p>
<p>解決的方法很簡單，我們只要在 IndexController 類別的上方加入：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Controller/Action.php'</span><span style="color: #339933;">;</span></pre></div></div>

<p>就可以再執行 Create PHPUnit tests 指令了。</p>
<p>完成後， NetBeans 就會產生 D:\WEB\zf\unittest\tests\application\controllers\IndexControllerTest.php 這個檔案了。</p>
<h2>測試 Controller</h2>
<p>雖然前面我們產生了 IndexControllerTest 這個測試類別，但是它卻不能用來測試 IndexController 的流程。這是因為我們沒有去啟動 Zend_Application 及相關的 Resource ，所以這裡我們要借重 Zend_Test 提供的 Zend_Test_PHPUnit_ControllerTestCase 類別來幫我們進行測試。請將 D:\WEB\zf\unittest\tests\application\controllers\IndexControllerTest.php 的內容改為：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> IndexControllerTest <span style="color: #000000; font-weight: bold;">extends</span> Zend_Test_PHPUnit_ControllerTestCase
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000000; font-weight: bold;">function</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bootstrap</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'appBootstrap'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        parent<span style="color: #339933;">::</span><span style="color: #004000;">setUp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> appBootstrap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	  	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>APPLICATION_ENV<span style="color: #339933;">,</span> APPLICATION_CONFIG<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	  	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">application</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bootstrap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testHome<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dispatch</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertAction</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;index&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertController</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;index&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertResponseCode</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>在這裡我們要借重 Zend_Test_PHPUnit_ControllerTestCase 提供的 bootstrap 機制，幫我們處理有關應用程式設定與 Front Controller 等相關資源的啟動；然後我們就可以簡單地透過 Zend_Test_PHPUnit_ControllerTestCase 提供的方法 (例如 dispatch ) ，來幫我們測試 Controller 的流程。</p>
<p>上面的例子裡我們只很簡單地測試首頁，至於更進階的 Controller 測試，有機會我會再分享給大家。</p>
<h2>進階的 phpunit.xml 設定</h2>
<p>在 phpunit.xml 中可以設定的項目很多，可以參考<a href="http://www.phpunit.de/manual/current/en/appendixes.configuration.html" target="_blank">官方手冊的說明</a>，這邊我們簡單地探討幾個常用的項目。</p>
<h3>testsuite</h3>
<p>testsuite 標籤主要是幫我們透過 PHPUnit_Framework_TestSuite 去組織多個測試類別，例如以下範例：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>phpunit bootstrap<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;./application/bootstrap.php&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>testsuite name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;My App&quot;</span><span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>directory<span style="color: #339933;">&gt;./&lt;/</span>directory<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>testsuite<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>phpunit<span style="color: #339933;">&gt;</span></pre></div></div>

<p>首先 testsuite 的 name 屬性是讓我們設定 Suite 的名稱，而 directory 標籤則是告訴 phpunit ，這個 Suite 包含了 D:\WEB\zf\unittest\tests 下所有檔名結尾為 Test.php 的測試檔案。</p>
<p>另外還要注意一點，在還沒加入 testsuite 之前，我們要在 D:\WEB\zf\unittest\tests 用 &quot;phpunit .&quot; 來指定目錄執行測試；而加入 testsuite 標籤後，我們就可以直接在 D:\WEB\zf\unittest\tests 執行 phpunit ，而不用再指定測試的路徑了。</p>
<h3>filter</h3>
<p>filter 標籤主要是幫我們過濾程式碼涵蓋範圍報告的項目，避免出現過多不相干類別的報告內容。 filter 分為白名單與黑名單兩種，以下我們以白名單為主：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>phpunit bootstrap<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;./application/bootstrap.php&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;!--</span> 略 <span style="color: #339933;">--&gt;</span>
    <span style="color: #339933;">&lt;</span>filter<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>whitelist<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;</span>directory suffix<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;.php&quot;</span><span style="color: #339933;">&gt;../</span>application<span style="color: #339933;">/&lt;/</span>directory<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;</span>exclude<span style="color: #339933;">&gt;</span>
            	<span style="color: #339933;">&lt;</span>file<span style="color: #339933;">&gt;../</span>application<span style="color: #339933;">/</span>Bootstrap<span style="color: #339933;">.</span>php<span style="color: #339933;">&lt;/</span>file<span style="color: #339933;">&gt;</span>
            	<span style="color: #339933;">&lt;</span>file<span style="color: #339933;">&gt;../</span>application<span style="color: #339933;">/</span>controllers<span style="color: #339933;">/</span>ErrorController<span style="color: #339933;">.</span>php<span style="color: #339933;">&lt;/</span>file<span style="color: #339933;">&gt;</span>
               <span style="color: #339933;">&lt;</span>directory suffix<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;.phtml&quot;</span><span style="color: #339933;">&gt;../</span>application<span style="color: #339933;">/&lt;/</span>directory<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;/</span>exclude<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;/</span>whitelist<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>filter<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>phpunit<span style="color: #339933;">&gt;</span></pre></div></div>

<p>這裡主要是告訴 phpunit 只處理 D:\WEB\zf\unittest\application 下的類別 (注意！不是 tests\application ！) ，但排除掉 D:\WEB\zf\unittest\application\Bootstrap.php 、 D:\WEB\zf\unittest\application\controllers\ErrorController.php 以及 D:\WEB\zf\unittest\application\ 下所有的 .phtml 樣板檔。</p>
<p>不過 filter 通常會搭配稍後要說明的 logging 標籤一起使用。</p>
<h3>logging</h3>
<p>logging 標籤主要用來產生測試報告，它支援相當多的格式，以下我們以 HTML 格式為主：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>phpunit bootstrap<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;./application/bootstrap.php&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;!--</span> 略 <span style="color: #339933;">--&gt;</span>
    <span style="color: #339933;">&lt;</span>logging<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>log type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;coverage-html&quot;</span> target<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;./log/report&quot;</span> charset<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;UTF-8&quot;</span>
            yui<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;true&quot;</span> highlight<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;true&quot;</span> lowUpperBound<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;50&quot;</span> highLowerBound<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;80&quot;</span><span style="color: #339933;">/&gt;</span>
        <span style="color: #339933;">&lt;</span>log type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;testdox-html&quot;</span> target<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;./log/testdox.html&quot;</span> <span style="color: #339933;">/&gt;</span>
    <span style="color: #339933;">&lt;/</span>logging<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>phpunit<span style="color: #339933;">&gt;</span></pre></div></div>

<p>在執行測試前，別忘了在 D:\WEB\zf\unittest\tests 下建立一個 log 目錄，避免 phpunit 回報錯誤。執行完測試後，就會在 D:\WEB\zf\unittest\tests\log 產生一個 testdox.html 檔案及一個 report 資料夾。</p>
<p>textdox.html 會以我們在測試類別裡寫的測試案例為名稱來做為驗證項目名稱，例如 testDoSomething 就會變成 Do something 。而用瀏覽器開啟 report/index.html 後，我們就能看到完整的程式碼覆蓋率報告。</p>
<h2>小結</h2>
<p>最後我們再整理一下重點：</p>
<ul>
<li>
<p>我們可以在專案中建立一個 tests 目錄，供我們放置測試類別。</p>
</li>
<li>
<p>PHPUnit 可以透過 phpunit.xml 及 bootstrap.php 來做自動化的測試環境。</p>
</li>
<li>
<p>phpunit.xml 主要是用來設定 phpunit 執行時的選項。</p>
</li>
<li>
<p>bootstrap.php 主要的工作是設定測試時會用到的環境常數、引入路徑以及類別自動載入機制等。</p>
</li>
<li>
<p>NetBeans 對 PHPUnit 有強大的支援，不論在建立測試及執行測試上，都非常直覺。</p>
</li>
<li>
<p>即便不使用 NetBeans ，我們還是可以透過 phpunit 這個 CLI 工具來完成自動化測試。</p>
</li>
</ul>
<p>雖然這裡我是以 Zend Framework 專案為主，但大家還是可以仿照這樣的機制，在自己的專案裡去建構自動化測試。</p>
<p>還猶豫什麼？快去試試吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2345/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHPUnit 實務入門簡介</title>
		<link>http://blog.wabow.com/archives/2299</link>
		<comments>http://blog.wabow.com/archives/2299#comments</comments>
		<pubDate>Tue, 16 Mar 2010 13:28:53 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[軟體測試]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2299</guid>
		<description><![CDATA[這幾天在寫折價券攤提到商品的數學演算法邏輯，搞得我七葷八素的...還好先前在製作購物車時，已經把單元測試放到架構裡，因此後面就只要專心應付演算法邏輯就好了。 雖然這樣的規劃聽起來不錯，但單元測試這件事說到底我的實務經驗還是太少，在這次的專案項目裡，才讓我真正有了較為深入的體會。 先對要測試的事情有一個概觀 其實測試一開始真的很難下手，主要是因為我們不知道我們要測些什麼東西。因此，我們需要對需要測試的東西有個概觀。 就以這次的例子來說吧，我要測試的東西就是「折價券攤提的演算法邏輯」，那它裡面重要的東西是什麼？ 在跟客戶討論，我們得知折價券面額要分攤到的商品上時有一定的規則；這時我們就要先在紙上作業，用簡單的例子跟客戶確認清楚規則。 確認了方向之後，因為我之前已經測試架構準備好了，所以接下來就只要針對要測試的部份撰寫程式碼即可。但如果一開始還沒有準備好測試架構的話，這裡給大家幾個建置環境的簡易流程： 在專案裡開個 tests 資料夾，這裡就是放置測試案例的地方。 準備一個 init.php ，目的是用來設置 include_path 及 autoload 機制。 按照 PHPUnit 官方的建議，建立一個 AllTests.php 的 Test Suite 。 註：這裡我就不列出程式碼了，讓大家自己試試看。 然後每次測試就用以下指令即可： &#62; phpunit AllTests.php 之後我會以「跑測試」來表示執行這個指令。 描繪程式的輪廓 接下來我們就要把整個系統的測試架構定義出來，不過這時候其實我們還沒開始寫程式，只是把流程和相關的方法先定義出來。 這裡的方法很簡單，就是先透過註解和方法介面來描述整個流程，而不是先寫細部的程式碼。 class Shop_Cart_Plugin_Coupon extends Shop_Cart_Plugin &#123; // ... 略 ... &#160; // 演算法計算後的結果 protected $_sharedCouponData = array&#40;&#41;; &#160; // 取得演算法計算後的結果，也可供測試來驗證 public functino [...]]]></description>
			<content:encoded><![CDATA[<p>這幾天在寫折價券攤提到商品的數學演算法邏輯，搞得我七葷八素的...還好先前在製作購物車時，已經把單元測試放到架構裡，因此後面就只要專心應付演算法邏輯就好了。</p>
<p>雖然這樣的規劃聽起來不錯，但單元測試這件事說到底我的實務經驗還是太少，在這次的專案項目裡，才讓我真正有了較為深入的體會。</p>
<p><span id="more-2299"></span></p>
<h2>先對要測試的事情有一個概觀</h2>
<p>其實測試一開始真的很難下手，主要是因為我們不知道我們要測些什麼東西。因此，我們需要對需要測試的東西有個概觀。</p>
<p>就以這次的例子來說吧，我要測試的東西就是「折價券攤提的演算法邏輯」，那它裡面重要的東西是什麼？</p>
<p>在跟客戶討論，我們得知折價券面額要分攤到的商品上時有一定的規則；這時我們就要先在紙上作業，用簡單的例子跟客戶確認清楚規則。</p>
<p class="image"><a href="http://www.jaceju.net/resources/phpunit/draft.jpg"><img src="http://www.jaceju.net/resources/phpunit/draft.jpg" alt="草圖" /></a></p>
<p>確認了方向之後，因為我之前已經測試架構準備好了，所以接下來就只要針對要測試的部份撰寫程式碼即可。但如果一開始還沒有準備好測試架構的話，這裡給大家幾個建置環境的簡易流程：</p>
<ol>
<li>
<p> 在專案裡開個 tests 資料夾，這裡就是放置測試案例的地方。</p>
</li>
<li>
<p> 準備一個 init.php ，目的是用來設置 include_path 及 autoload 機制。</p>
</li>
<li>
<p> 按照 PHPUnit 官方的建議，建立一個 AllTests.php 的 Test Suite 。</p>
</li>
</ol>
<p class="note">註：這裡我就不列出程式碼了，讓大家自己試試看。</p>
<p>然後每次測試就用以下指令即可：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; phpunit AllTests.php</pre></div></div>

<p>之後我會以「跑測試」來表示執行這個指令。</p>
<h2>描繪程式的輪廓</h2>
<p>接下來我們就要把整個系統的測試架構定義出來，不過這時候其實我們還沒開始寫程式，只是把流程和相關的方法先定義出來。</p>
<p>這裡的方法很簡單，就是先透過註解和方法介面來描述整個流程，而不是先寫細部的程式碼。</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Shop_Cart_Plugin_Coupon <span style="color: #000000; font-weight: bold;">extends</span> Shop_Cart_Plugin
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// 演算法計算後的結果</span>
    protected <span style="color: #000088;">$_sharedCouponData</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// 取得演算法計算後的結果，也可供測試來驗證</span>
    <span style="color: #000000; font-weight: bold;">public</span> functino getSharedCouponData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_sharedCouponData<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// 主要的執行方法</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> doCheckout<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getCouponData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 取得</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getProductData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 取得商品資料</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_initData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 初始化要攤提的資料</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_shareCouponToProduct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 開始攤提</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>當然這些都是大概的輪廓，因為可能在我們寫好測試執行時，會再額外加入新的方法及介面。</p>
<p>還有一個要先定義好的是測試用的比對數據格式，它對我們稍後要測試的程式寫法會有影響。</p>
<h2>寫第一個測試</h2>
<p>到這裡，我們就可以開始寫第一個測試，而接下來的程式碼，都是先以這個測試可以成功為目的。而這個測試要怎麼寫呢？就是把一開始我們在紙上作業的數字拿進來套用。</p>
<p>當然這裡我的 setUp 和 tearDown 也已經在之前準備測試架構時寫好了，它們會讓我們每次的測試數據都能夠獨立。我們關心的就是第一個測試案例：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> Shop_Cart_Plugin_CouponTest <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Framework_TestCase
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testDoCheckout<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
           <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// C1, ProductCoupon for P1, $100</span>
           <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// C2, ProductCoupon for P1, P2, $100</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_cart<span style="color: #339933;">-&gt;</span><span style="color: #004000;">addItems</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'P1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// $200</span>
            <span style="color: #0000ff;">'P2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// $300</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">refresh</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">300</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_cart<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTotal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">doCheckout</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$resultDataList</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSelectedOrderCouponDataList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">100</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resultDataList</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'P1-C1'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'discountPrice'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">25</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$resultDataList</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'P1-C2'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'discountPrice'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">75</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$resultDataList</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'P2-C2'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'discountPrice'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>這裡因為我們在上一步就定義好比對用的數據，所以測試時就是用這個輸出的數據來與我們預期的數字相比較。</p>
<p>接下來就先跑跑測試，看看這個 TestCase 有沒有執行錯誤的地方 (例如物件沒有正確初始化或是變數名稱誤寫等等) ；當然如果沒有出現預期值是正常的，因為我們根本還沒有寫計算公式。</p>
<h2>繼續完成演算法</h2>
<p>現在回到 Shop_Cart_Plugin_Coupon ，我們就要把剛剛那些只有骨頭的方法開始添血添肉，這裡就請大家自行發擇。</p>
<p>接著只要你覺得程式差不多了，就先跑一下測試，看看是不是符合測試的預期結果。</p>
<p>當你完成第一個測試時，程式的就差不多完成百分之五十啦，到這裡別忘了先把程式 commit 到版本控制系統裡。</p>
<h2>加入新測試並修改程式</h2>
<p>完成第一個測試時，當然不是沒事了，我們要針對不同的狀況再加入其他的測試數據。</p>
<p>這裡我們就可以開始考慮把第一個測試以 PHPUnit 提供的 Data Provider 改寫，讓我們不必重複過多的程式碼。</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> Shop_Cart_Plugin_CouponTest <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Framework_TestCase
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @dataProvider provider
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testDoCheckout<span style="color: #009900;">&#40;</span><span style="color: #000088;">$selectedCouponIdList</span><span style="color: #339933;">,</span> <span style="color: #000088;">$productSkuNumberList</span><span style="color: #339933;">,</span> <span style="color: #000088;">$total</span><span style="color: #339933;">,</span> <span style="color: #000088;">$discountDataList</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$selectedCouponIdList</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_cart<span style="color: #339933;">-&gt;</span><span style="color: #004000;">addItems</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$productSkuNumberList</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">refresh</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$total</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_cart<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTotal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">doCheckout</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$resultDataList</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_plugin<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSharedCouponData</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$discountDataList</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resultDataList</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'discountPrice'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> provider<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #666666; font-style: italic;">// 第一個測試</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// C1, ProductCoupon for P1, $100</span>
                <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// C2, ProductCoupon for P1, P2, $100</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'P1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// $200</span>
                <span style="color: #0000ff;">'P2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// $300</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">300</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'P1-C1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">100</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'P1-C2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">25</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'P2-C2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">75</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #666666; font-style: italic;">// 第二個測試</span>
                <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #666666; font-style: italic;">// ... 略 ...</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>而加入新測試之後，就可以跑跑測試，看看我們剛寫好的演算法是否正確動作？通常這時候才真正是考驗的開始。因為這時候前面寫好的程式碼可能只對第一個測試正常，接下來的測試也許就會出錯了。</p>
<p>所以我們就會需要修改或重構程式碼，讓後面的測試也能正常執行。當然改過的程式也要讓第一個測試正常運作，才是正確的修改。</p>
<p>當然演算法寫好後，就要真正上到 Web 畫面去測試。至此，你會發現你花在寫測試上的心力都有了回報，因為通常如果你已經定義好介面，而這次的修改只是改寫一個小類別的話，那麼就會發現程式會非常順利地運作了。</p>
<h2>心得</h2>
<p>每次寫購物車時，最麻煩的就是測試時要開啟購物車網頁，把一個一個的商品加進來，再加入不同的折價券條件...</p>
<p>而有單元測試之後，我就可以省去一大堆開啟網頁，點選連結的功夫，專心地撰寫計算邏輯...只能說...單元測試真的個超級便利的工具呀。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2299/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[轉載][SVN] 為 Subversion 的 post-commit mail 加入專案名稱</title>
		<link>http://blog.wabow.com/archives/2112</link>
		<comments>http://blog.wabow.com/archives/2112#comments</comments>
		<pubDate>Fri, 02 Oct 2009 12:21:06 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2112</guid>
		<description><![CDATA[本文轉載自：[SVN] 為 Subversion 的 post-commit mail 加入專案名稱 問題 目前我們公司是用 Subversion 做為版本控管系統，在 commit 時都會需要把版本更新訊息寄送給相關人員，當然這就會用到 post-commit 這個 hook 指令；而在 post-commit 中，我們可以利用 bash 語法去呼叫寄信程式。 不過預設建立好的 Repository 下的 hooks 目錄並沒有這個檔案，我們可以把預設的 post-commit.tmpl 複製成 post-commit ： # cp /path-to-svn-repository/project_name/hooks/post-commit.tmpl /path-to-svn-repository/project_name/hooks/post-commit 至於寄信程式的部份，在 Subversion 的 Source code 裡就提供了一個很有用的 mailer.py ，它可以協助我們寄送 commit 後的訊息。 原來的 post-commit 內容如下： #!/bin/sh &#160; # POST-COMMIT HOOK # (略) &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>本文轉載自：<a href="http://www.jaceju.net/blog/?p=733">[SVN] 為 Subversion 的 post-commit mail 加入專案名稱</a></p>
<h2>問題</h2>
<p>目前我們公司是用 Subversion 做為版本控管系統，在 commit 時都會需要把版本更新訊息寄送給相關人員，當然這就會用到 post-commit 這個 hook 指令；而在 post-commit 中，我們可以利用 bash 語法去呼叫寄信程式。</p>
<p><span id="more-2112"></span></p>
<p>不過預設建立好的 Repository 下的 hooks 目錄並沒有這個檔案，我們可以把預設的 post-commit.tmpl 複製成 post-commit ：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># cp /path-to-svn-repository/project_name/hooks/post-commit.tmpl /path-to-svn-repository/project_name/hooks/post-commit</pre></div></div>

<p>至於寄信程式的部份，在 Subversion 的 Source code 裡就提供了一個很有用的 mailer.py ，它可以協助我們寄送 commit 後的訊息。</p>
<p>原來的 post-commit 內容如下：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># POST-COMMIT HOOK</span>
<span style="color: #666666; font-style: italic;"># (略)</span>
&nbsp;
<span style="color: #007800;">REPOS</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
<span style="color: #007800;">REV</span>=<span style="color: #ff0000;">&quot;$2&quot;</span>
&nbsp;
commit-email.pl <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REPOS</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REV</span>&quot;</span> commit-watchers<span style="color: #000000; font-weight: bold;">@</span>example.org
log-commit.py <span style="color: #660033;">--repository</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REPOS</span>&quot;</span> <span style="color: #660033;">--revision</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REV</span>&quot;</span></pre></div></div>

<p>將它修改為：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh    </span>
&nbsp;
<span style="color: #666666; font-style: italic;"># POST-COMMIT HOOK </span>
<span style="color: #666666; font-style: italic;"># (略) </span>
&nbsp;
<span style="color: #007800;">REPOS</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
<span style="color: #007800;">REV</span>=<span style="color: #ff0000;">&quot;$2&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>path-to-subversion-source<span style="color: #000000; font-weight: bold;">/</span>tools<span style="color: #000000; font-weight: bold;">/</span>hook-scripts<span style="color: #000000; font-weight: bold;">/</span>mailer<span style="color: #000000; font-weight: bold;">/</span>mailer.py commit <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REPOS</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REV</span>&quot;</span>
<span style="color: #666666; font-style: italic;"># log-commit.py --repository &quot;$REPOS&quot; --revision &quot;$REV&quot;</span></pre></div></div>

<p>不過用原始的 mailer.py 有個缺點，主要是它寄送的訊息主旨範例如下：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">r3214 - branches/2.0</pre></div></div>

<p>這樣在多個專案時，我們就不容易識別這次的更新是哪個專案。</p>
<p>所以我就想透過修改 mailer.py ，讓它產生如下的主旨：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[project_name] r3214 - branches/2.0</pre></div></div>

<h2>修改方式</h2>
<p>改法很簡單，有兩個地方要改： (針對 Subversion 版本 1.4.4 原始檔)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> commondir:
  <span style="color: #008000;">self</span>.<span style="color: black;">output</span>.<span style="color: black;">subject</span> = <span style="color: #483d8b;">'r%d - in %s: %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>repos.<span style="color: black;">rev</span>, commondir, dirlist<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
  <span style="color: #008000;">self</span>.<span style="color: black;">output</span>.<span style="color: black;">subject</span> = <span style="color: #483d8b;">'r%d - %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>repos.<span style="color: black;">rev</span>, dirlist<span style="color: black;">&#41;</span></pre></div></div>

<p>改成：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> commondir:
  <span style="color: #008000;">self</span>.<span style="color: black;">output</span>.<span style="color: black;">subject</span> = <span style="color: #483d8b;">'[%s] r%d - in %s: %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>repos.<span style="color: black;">project_name</span>, repos.<span style="color: black;">rev</span>, commondir, dirlist<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
  <span style="color: #008000;">self</span>.<span style="color: black;">output</span>.<span style="color: black;">subject</span> = <span style="color: #483d8b;">'[%s] r%d - %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>repos.<span style="color: black;">project_name</span>, repos.<span style="color: black;">rev</span>, dirlist<span style="color: black;">&#41;</span></pre></div></div>

<p>也就是這裡我多加了一個 repos.project_name ，讓信件主旨可以多一個專案名稱。不過 projects_name 並不是 repos 的屬性，所以我們還要再修改一個地方。</p>
<p>往下找到：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">author</span> = <span style="color: #008000;">self</span>.<span style="color: black;">get_rev_prop</span><span style="color: black;">&#40;</span>svn.<span style="color: black;">core</span>.<span style="color: black;">SVN_PROP_REVISION_AUTHOR</span><span style="color: black;">&#41;</span></pre></div></div>

<p>然後在底下加入一行：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">self</span>.<span style="color: black;">project_name</span> = repos_dir<span style="color: black;">&#91;</span><span style="color: #ff4500;">10</span>:<span style="color: black;">&#93;</span></pre></div></div>

<p>其中 10 這個數字是指 /path-to-svn-repository/ 的長度，因為 repos_dir 的內容會是 /path-to-svn-repository/project-name ，而字串是由 0 開始算起，那麼 project_name 的起始位置就會剛好是 /path-to-svn-repository/ 的長度。 (所以請自行計算並更改之)</p>
<p>至於為什麼我會知道 repos_dir 的內容，這是因為我在一開始就用了以下的程式去印出它：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;mailer.log&quot;</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>repos_dir<span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>當然這邊要注意縮排。</p>
<h2>結論</h2>
<p>Python 對我來說，其實是一個不熟悉的語言。不過它的語法也不是那麼難以理解，以我這種三流能力，竟然還能看懂並修改它。</p>
<p>而 mailer.py 也大量使用了物件導向的寫法，所以未來有機會在開發 Python 程式時，在物件導向的基礎也是不可或缺的。</p>
<p>就這樣啦~謝謝收看~再會~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2112/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP]免費的檔案瀏覽工具 fileNice</title>
		<link>http://blog.wabow.com/archives/2106</link>
		<comments>http://blog.wabow.com/archives/2106#comments</comments>
		<pubDate>Thu, 27 Aug 2009 07:34:03 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[軟體測試]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2106</guid>
		<description><![CDATA[官方網站 http://filenice.com/ 展示網頁 http://filenice.com/demo/ 介紹 filenice是一套用php編寫的檔案瀏覽工具，作用在你本身如果有架設網站並有某個資料夾提供上傳檔案，當你想要查看這個資料夾中有哪些檔案時，filenice提供使用瀏覽器就可以查看的功能。 安裝 到官網下載檔案(http://filenice.com/demo/fileNice.zip)，下載完畢將解壓縮後的檔案放到網站伺服器上你想要瀏覽檔案的資料夾下即可。 優點 官方的說明是filenice是使用php+javascript也就是所謂的Ajax技術編寫的，因此速度比較快，而且當應用程式忙碌時可以返回而不會整個畫面當掉。此外使用filenice不需要安裝任何資料庫。 感想 filenice提供了無須安裝其他軟體，僅需使用瀏覽器就可觀看主機上提供upload的資料夾下的內容，也可自訂瀏覽檔案的一些排列等細節，另外也提供搜尋的功能。不過個人比較覺得可惜的是，因為無須登入帳密即可觀看，在安全性上稍顯不足，不過或是也因此除了觀看以外，並沒有額外提供刪除或是上傳的功能吧!?介紹給大家用看看!]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.wabow.com/wp-content/uploads/2009/08/sample10-500x260.gif" alt="sample10" width="500" height="260" class="aligncenter size-large wp-image-2107" /></p>
<p>官方網站  <a href="http://filenice.com/">http://filenice.com/</a><br />
展示網頁  <a href="http://filenice.com/demo/">http://filenice.com/demo/</a><span id="more-2106"></span></p>
<h3>介紹</h3>
<p>filenice是一套用php編寫的檔案瀏覽工具，作用在你本身如果有架設網站並有某個資料夾提供上傳檔案，當你想要查看這個資料夾中有哪些檔案時，filenice提供使用瀏覽器就可以查看的功能。</p>
<h3>安裝</h3>
<p>到官網下載檔案(http://filenice.com/demo/fileNice.zip)，下載完畢將解壓縮後的檔案放到網站伺服器上你想要瀏覽檔案的資料夾下即可。</p>
<h3>優點</h3>
<p>官方的說明是filenice是使用php+javascript也就是所謂的Ajax技術編寫的，因此速度比較快，而且當應用程式忙碌時可以返回而不會整個畫面當掉。此外使用filenice不需要安裝任何資料庫。</p>
<h3>感想</h3>
<p>filenice提供了無須安裝其他軟體，僅需使用瀏覽器就可觀看主機上提供upload的資料夾下的內容，也可自訂瀏覽檔案的一些排列等細節，另外也提供搜尋的功能。不過個人比較覺得可惜的是，因為無須登入帳密即可觀看，在安全性上稍顯不足，不過或是也因此除了觀看以外，並沒有額外提供刪除或是上傳的功能吧!?介紹給大家用看看!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2106/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[PHP] PHP 密技： include 與 require</title>
		<link>http://blog.wabow.com/archives/2104</link>
		<comments>http://blog.wabow.com/archives/2104#comments</comments>
		<pubDate>Thu, 27 Aug 2009 07:25:54 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2104</guid>
		<description><![CDATA[轉載自：[PHP] PHP 密技： include 與 require 可以接受回傳資料？ 先調查一下，知道 include 或 require 可以取得回傳資料的請舉手... (眺望) 呃...不知道的朋友也不用煩惱，我來解釋一下。 如何回傳資料呢？假設現在有個 php 檔叫做 config.php ，內容如下： &#60;?php return array&#40;'123', '456'&#41;; 咦？那邊有人說 return 放錯地方了？不不不， PHP 能接受這樣的寫法。 好，現在我們來證明 include 或 require 能取得 config.php 所 return 回來的資料。請建立一支 test.php ，其內容是： $config = require 'config.php'; var_dump&#40;$config&#41;; 執行看看，是不是可以跑呀？ 所以我們可以在某支 PHP 程式中 return 一個資料 (任何型態) ，然後在另一支 PHP 程式中用 include [...]]]></description>
			<content:encoded><![CDATA[<p>轉載自：<a href="http://www.jaceju.net/blog/?p=316">[PHP] PHP 密技： include 與 require</a></p>
<h2>可以接受回傳資料？</h2>
<p>先調查一下，知道 include 或 require 可以取得回傳資料的請舉手... (眺望)</p>
<p>呃...不知道的朋友也不用煩惱，我來解釋一下。</p>
<p><span id="more-2104"></span></p>
<p>如何回傳資料呢？假設現在有個 php 檔叫做 config.php ，內容如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'123'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'456'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>咦？那邊有人說 return 放錯地方了？不不不， PHP 能接受這樣的寫法。</p>
<p>好，現在我們來證明 include 或 require 能取得 config.php 所 return 回來的資料。請建立一支 test.php ，其內容是：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>執行看看，是不是可以跑呀？</p>
<p>所以我們可以在某支 PHP 程式中 return 一個資料 (任何型態) ，然後在另一支 PHP 程式中用 include 或 require 來取得這個資料。 </p>
<h2>把 require 放在參數裡 </h2>
<p>什麼？這不是密技？不不不，密技在底下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> test<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
test<span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>對！你沒看錯！直接把 require 放在函式的參數裡！</p>
<p>還沒完呢，再看：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Test
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Test<span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>連 new 建構子的參數都可以接受 require ！</p>
<p>所以只要能放變數的地方，都可以放 include 或 require ，例如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>而且不僅是 include 及 require ，連 include_once 和 require_once 都可以這麼做。</p>
<p>我在<a href="http://blog.astrumfutura.com/archives/340-The-Zend-Framework,-Dependency-Injection-and-Zend_Di.html">某篇文章</a>發現這個密技以後，分享給辦公室裡的同事們；沒想到玩了 PHP 這麼多年的他們也沒看過這個方法，看來大家對 PHP 的瞭解需要更深入一點囉！</p>
<h2>Scope 的問題 </h2>
<p>接著我同事問了我一個問題：如果在參數使用 require 敘述，而且被 require 的 PHP 程式裡如果有定義全域變數的話，那麼這個變數在執行的 PHP 程式裡，它的 scope 在哪裡呢？</p>
<p>答案是：它還是全域。</p>
<p>怎麼說呢？現在我們在剛剛的 config.php 的 return 敘述前加上一行程式，如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'789'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 加上這行</span>
<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'123'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'456'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>然後在 test.php 裡的 Global 部份 (也就是不在函式或類別定義裡) 的任意處加入：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>是不是也可以正確顯示 config.php 中 $data 變數所指定的內容呢？這就表示在參數中使用 require 不會影響全域變數的 scope 。</p>
<p>還有其他 include 或 require 的密技嗎？歡迎大家一起討論囉~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2104/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用 PHP 查 DOMAIN 的 CNAME 紀錄</title>
		<link>http://blog.wabow.com/archives/2066</link>
		<comments>http://blog.wabow.com/archives/2066#comments</comments>
		<pubDate>Thu, 27 Aug 2009 06:44:34 +0000</pubDate>
		<dc:creator>suzy</dc:creator>
				<category><![CDATA[軟體測試]]></category>
		<category><![CDATA[cname]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2066</guid>
		<description><![CDATA[接獲一項來自 Neo 的任務, "用PHP 實作由 CNAME 去判定新加入服務的 DOMAIN 為申請人所有" (證明他不是來亂的). For Example: Google Apps 就是用這個方式去作驗證 CNAME 是 DOMAIN or SUB DOMAIN 指向另一個 DOMAIN 的方式. (跟 alias 一樣) 那麼如果要用 PHP 實作呢? 有兩種方式 : 1. PHP5 內建的 dns_get_record() (Windows &#38; BSD &#38; Mac 不適用) 2. PEAR NET_DNS NET_DNS 原理是用 fsockopen("你的 DNS SERVER IP", 53), 但是要先自己組合出 "封包的header data" [...]]]></description>
			<content:encoded><![CDATA[<p>接獲一項來自 Neo 的任務, "用PHP 實作由 CNAME 去判定新加入服務的 DOMAIN 為申請人所有" (證明他不是來亂的).</p>
<p>For Example:<br />
<a href="http://www.google.com/support/a/bin/answer.py?hl=b5&amp;answer=92354">Google Apps 就是用這個方式去作驗證</a><br />
<span id="more-2066"></span></p>
<p><a href="http://www.google.com.tw/search?hl=zh-TW&amp;q=CNAME">CNAME</a> 是 DOMAIN or SUB DOMAIN 指向另一個 DOMAIN 的方式. (跟 alias 一樣)</p>
<p>那麼如果要用 PHP 實作呢? 有兩種方式 :<br />
1. PHP5 內建的 dns_get_record() (Windows &amp; BSD &amp; Mac 不適用)<br />
2. PEAR <a href="http://pear.php.net/package/Net_DNS">NET_DNS</a></p>
<p>NET_DNS 原理是用 fsockopen("你的 DNS SERVER IP", 53),<br />
但是要先自己組合出 "封包的header data" 再丟過去, DNS Server 才會理你唷.<br />
這些複雜的部份 NET_DNS 已經都幫我們做好了.</p>
<p>我們只要:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Net/DNS.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$ndr</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Net_DNS_Resolver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$answer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$ndr</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">search</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;www.OOO.com&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;CNAME&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;pre&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$answer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 獲得的結果</span>
<span style="color: #990000;">Array</span>
<span style="color: #009900;">&#40;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> Net_DNS_RR_CNAME Object
        <span style="color: #009900;">&#40;</span>
            <span style="color: #009900;">&#91;</span>name<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> www<span style="color: #339933;">.</span>OOO<span style="color: #339933;">.</span>co<span style="color: #339933;">.</span>nz
            <span style="color: #009900;">&#91;</span>type<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> CNAME
            <span style="color: #009900;">&#91;</span><span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> IN
            <span style="color: #009900;">&#91;</span>ttl<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">86400</span>
            <span style="color: #009900;">&#91;</span>rdlength<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">18</span>
            <span style="color: #009900;">&#91;</span>rdata<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> store	XXX�<span style="color: #cc66cc;">3</span>
            <span style="color: #009900;">&#91;</span>cname<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> store<span style="color: #339933;">.</span>XXX<span style="color: #339933;">.</span>com
        <span style="color: #009900;">&#41;</span>
&nbsp;
<span style="color: #009900;">&#41;</span></pre></div></div>

<p>PS, 在 Windows 環境, 請修改 PEAR/NET/DNS/Resolver.php 裡的</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$resolv_conf</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/etc/resolv.conf'</span><span style="color: #339933;">;</span></pre></div></div>

<p>改成</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$resolv_conf</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'D:\Appserv\resolv.conf'</span><span style="color: #339933;">;</span></pre></div></div>

<p>resolv.conf 要加入你的 DNS Server (請用 ipconfig /all 查詢)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">nameserver 168<span style="color: #339933;">.</span>95<span style="color: #339933;">.</span>192<span style="color: #339933;">.</span>1</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2066/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Subversion] Setup In Windows</title>
		<link>http://blog.wabow.com/archives/2067</link>
		<comments>http://blog.wabow.com/archives/2067#comments</comments>
		<pubDate>Thu, 27 Aug 2009 06:41:19 +0000</pubDate>
		<dc:creator>abu</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2067</guid>
		<description><![CDATA[版本控管是個相當方便的程式開發好幫手，不管檔案被改到多爛，甚至不小心誤殺，都能輕鬆救回。 平常使用的安裝在哇寶主機上的subversion，這次想嘗試看看將subversion架設在windows平台上，於是開始了尋找資料之旅。 基本上，這裡有很詳細的說明，只要按照個人系統，修改部份設定，以下就紀錄一下我自己的步驟： (因為已經寫的超白話了，所以就不另外附圖) 安裝apache，我是用懶人包xampp直接裝好apache、php、mysql，apache版本2.2.9。  (  範例懶人包安裝的路徑是在c:\xampp\ )     點我下載xampp (版本 1.7.2 ) 下載subversion windows版本，點我下載  (版本 1.6.5 ) ， 安裝很容易，狂點next就對了。 打開C:\xampp\apache\conf\httpd.conf ，隨便找個地方 加入 &#60;Location /svn/repository&#62; DAV svn SVNPath D:\svn\repository &#60;/Location&#62; 其中 /svn/repository 是你想對應到的網址，像是 http://localhost/svn/repository， 而D:\svn\repository 則是實際svn專案檔案放置的位置。 最後，請到windows提供的"命令提示字元"模式下，輸入 svnadmin create d:/svn/repository ，完成建立專案，到這裡算是完成建立整個專案。 打開瀏覽器，輸入http://localhost:8080/svn/repository/ ，可以看到 『 repository - Revision 0: / 』，代表該專案目前版號為0 (還沒開始動工，當然是0) 測試一下，先隨便找個地方，例如 D:\wwwroot\ ，滑鼠右鍵選擇『 SVN 取出 [...]]]></description>
			<content:encoded><![CDATA[<p>版本控管是個相當方便的程式開發好幫手，不管檔案被改到多爛，甚至不小心誤殺，都能輕鬆救回。<span id="more-2067"></span></p>
<p>平常使用的安裝在哇寶主機上的subversion，這次想嘗試看看將subversion架設在windows平台上，於是開始了尋找資料之旅。<br />
基本上，<a href="http://liangkuo.blogspot.com/2007/03/svn-subversion-tortoisesvn.html">這裡</a>有很詳細的說明，只要按照個人系統，修改部份設定，以下就紀錄一下我自己的步驟：</p>
<p>(因為已經寫的超白話了，所以就不另外附圖)  </p>
<ul>
<li> 安裝apache，我是用懶人包xampp直接裝好apache、php、mysql，apache版本2.2.9。  (  範例懶人包安裝的路徑是在c:\xampp\ )     <a href="http://www.apachefriends.org/download.php?xampp-win32-1.7.2.exe">點我下載xampp</a> (版本 1.7.2 )</li>
<li>下載subversion windows版本，<a href="http://subversion.tigris.org/files/documents/15/46531/Setup-Subversion-1.6.5.msi">點我下載</a>  (版本 1.6.5 ) ， 安裝很容易，狂點next就對了。</li>
<li>打開C:\xampp\apache\conf\httpd.conf ，隨便找個地方 加入
<pre lang="html4strict" escaped="ture">
  &lt;Location /svn/repository&gt;
    DAV svn
    SVNPath D:\svn\repository
  &lt;/Location&gt;
</pre>
<p>其中 /svn/repository 是你想對應到的網址，像是 http://localhost/svn/repository， 而D:\svn\repository 則是實際svn專案檔案放置的位置。</li>
<li>最後，請到windows提供的"命令提示字元"模式下，輸入 svnadmin create d:/svn/repository ，完成建立專案，到這裡算是完成建立整個專案。</li>
<li>打開瀏覽器，輸入http://localhost:8080/svn/repository/ ，可以看到 『 repository - Revision 0: / 』，代表該專案目前版號為0 (還沒開始動工，當然是0)</li>
<li>測試一下，先隨便找個地方，例如 D:\wwwroot\ ，滑鼠右鍵選擇『 SVN 取出 』，檔案庫URL 請輸入 『 http://localhost:8080/svn/repository 』，取出目錄按照預設即可，按下確定。</li>
<li>到D:\wwwroot\repository，測試建立一個文字檔， aaa.txt ，同樣路徑下按滑鼠右鍵『 SVN 送交 』，將更新的檔案傳送至SVN檔案庫，完成測試SVN上傳。</li>
<li>同樣來到 http://localhost:8080/svn/repository/ ，會看到『 repository - Revision 1: / 』，版號以由0變成1，代表剛上傳的svn紀錄已完成。</li>
<p>以上就是依照個人設定，完成subversion安裝在windows的過程，看到專案是使用自己架設的subversion，檔案成功被建立、刪除修改後更新，感覺還不錯～</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2067/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[分享] 垃圾留言判斷，隱藏驗證碼的 NoSpamNX class PART2</title>
		<link>http://blog.wabow.com/archives/2072</link>
		<comments>http://blog.wabow.com/archives/2072#comments</comments>
		<pubDate>Thu, 27 Aug 2009 06:32:14 +0000</pubDate>
		<dc:creator>daniel</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[NoSpamNX]]></category>
		<category><![CDATA[垃圾留言]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=2072</guid>
		<description><![CDATA[感謝上一篇文章中前輩們的熱心回覆；垃圾留言果然是大家心中的痛啊（噗）～雖然 CAPTCHA 可以透過各式各樣的 OCR 破解（最新版的 JDownloader 也已經能忽略大部分免費空間所用的圖像辨識...扯遠了），不過它仍是目前阻擋機器人最直接也最簡單的解決方案；當然更複雜的 CAPTCHA 還是能夠達到阻擋的目的，但是使用 CAPTCHA 的方式對使用者來說就已經是不友善了。 後來在討論中 Jace 提到，其實 SESSION 是有可能被機器人知道的；所以我後來綜合了 fillano 提供的演算法概念，稍微改良了一下之前的 NoSpamNX class。利用隨機產生的隱藏欄位順序，用不同的演算法再對隱藏欄位的數值作編碼；讓 SESSION 內存的未編碼的值，與 POST 過來的已編碼的值不一樣。最後再將 SESSION 內存的值編碼，與 POST 的已編碼的值作比較，判斷留言的使用者是不是機器人。 SESSION 紀錄的值是未編碼的值，但在產生隱藏欄位時，input 的值是已經編碼過後的值 /** &#xa0;* 建立隱藏欄位 HTML；利用隱藏欄位先後順序不同，使用 md5 or sha1 編碼 &#xa0;* &#xa0;*/ public function addHiddenFields() { &#xa0;&#xa0;&#xa0;&#xa0;$nospamnx = $_SESSION[$this-&#62;_sessionName]; &#xa0;&#xa0;&#xa0;&#xa0;if (1 === rand(1,2)) { &#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;return '&#60;input [...]]]></description>
			<content:encoded><![CDATA[<p>感謝<a href="http://blog.wabow.com/archives/1974" target="_blank">上一篇文章</a>中前輩們的熱心回覆；垃圾留言果然是大家心中的痛啊（噗）～雖然 <a href="http://zh.wikipedia.org/w/index.php?title=CAPTCHA&amp;variant=zh-tw" target="_blank">CAPTCHA</a> 可以透過各式各樣的 <a href="http://zh.wikipedia.org/zh-tw/%E5%85%89%E5%AD%A6%E5%AD%97%E7%AC%A6%E8%AF%86%E5%88%AB" target="_blank">OCR</a> 破解（最新版的 <a href="http://jdownloader.org/home/index" target="_blank">JDownloader</a> 也已經能忽略大部分免費空間所用的圖像辨識...扯遠了），不過它仍是目前阻擋機器人最直接也最簡單的解決方案；當然更複雜的 CAPTCHA 還是能夠達到阻擋的目的，但是使用 CAPTCHA 的方式對使用者來說就已經是不友善了。</p>
<p>後來在討論中 Jace 提到，其實 SESSION 是有可能被機器人知道的；所以我後來綜合了 fillano 提供的演算法概念，稍微改良了一下之前的 NoSpamNX class。利用隨機產生的隱藏欄位順序，用不同的演算法再對隱藏欄位的數值作編碼；讓 SESSION 內存的未編碼的值，與 POST 過來的已編碼的值不一樣。最後再將 SESSION 內存的值編碼，與 POST 的已編碼的值作比較，判斷留言的使用者是不是機器人。</p>
<p><span id="more-2072"></span>SESSION 紀錄的值是未編碼的值，但在產生隱藏欄位時，input 的值是已經編碼過後的值</p>
<pre style='color:#000020;background:#cceeee;overflow:auto;border:1px solid silver'>
<span style='color:#595979;background:#cceeee'>/**</span>
<span style='color:#595979;background:#cceeee'>&#xa0;* 建立隱藏欄位 HTML；利用隱藏欄位先後順序不同，使用 md5 or sha1 編碼</span>
<span style='color:#595979;background:#cceeee'>&#xa0;* </span>
<span style='color:#595979;background:#cceeee'>&#xa0;*/</span>
<span style='color:#200080;background:#cceeee;font-weight:bold'>public</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#200080;background:#cceeee;font-weight:bold'>function</span><span style='color:#000000;background:#cceeee'> addHiddenFields</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#007d45;background:#cceeee'>$_SESSION</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#007d45;background:#cceeee'>$</span><span style='color:#200080;background:#cceeee;font-weight:bold'>this</span><span style='color:#308080;background:#cceeee'>-&gt;</span><span style='color:#007d45;background:#cceeee'>_sessionName</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#200080;background:#cceeee;font-weight:bold'>if</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#008c00;background:#cceeee'>1</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#400000;background:#cceeee'>rand</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#008c00;background:#cceeee'>1</span><span style='color:#308080;background:#cceeee'>,</span><span style='color:#008c00;background:#cceeee'>2</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#200080;background:#cceeee;font-weight:bold'>return</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#1060b6;background:#cceeee'>'&lt;input type="text" name="nospamnx['</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-1'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>']" value="" class="locktross" /&gt;&lt;input type="text" name="nospamnx['</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>']" value="'</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#400000;background:#cceeee'>md5</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2-value'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>'" class="locktross" /&gt;'</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#200080;background:#cceeee;font-weight:bold'>else</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#200080;background:#cceeee;font-weight:bold'>return</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#1060b6;background:#cceeee'>'&lt;input type="text" name="nospamnx['</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>']" value="'</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#400000;background:#cceeee'>sha1</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2-value'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>'" class="locktross" /&gt;&lt;input type="text" name="nospamnx['</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-1'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>.</span><span style='color:#1060b6;background:#cceeee'>']" value="" class="locktross" /&gt;'</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'></span>
</pre>
<p>驗證時根據 POST 過來的 nospamnx 順序不同，以不同的演算法編碼後再做比較</p>
<pre style='color:#000020;background:#cceeee;overflow:auto;border:1px solid silver'>
<span style='color:#595979;background:#cceeee'>// 根據 POST 過來的值順序不同，以 md5 or sha1 判斷</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#200080;background:#cceeee;font-weight:bold'>if</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-1'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#400000;background:#cceeee'>current</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#400000;background:#cceeee'>array_keys</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$postData</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#007d45;background:#cceeee'>$encode_value</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#400000;background:#cceeee'>md5</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2-value'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#200080;background:#cceeee;font-weight:bold'>else</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#007d45;background:#cceeee'>$encode_value</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#400000;background:#cceeee'>sha1</span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2-value'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#200080;background:#cceeee;font-weight:bold'>if</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>(</span><span style='color:#007d45;background:#cceeee'>$postData</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#007d45;background:#cceeee'>$nospamnx</span><span style='color:#308080;background:#cceeee'>[</span><span style='color:#1060b6;background:#cceeee'>'nospamnx-2'</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#308080;background:#cceeee'>]</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#308080;background:#cceeee'>!</span><span style='color:#308080;background:#cceeee'>=</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#007d45;background:#cceeee'>$encode_value</span><span style='color:#308080;background:#cceeee'>)</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#406080;background:#cceeee'>{</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#000000;background:#cceeee'>&#xa0;&#xa0;&#xa0;&#xa0;</span><span style='color:#200080;background:#cceeee;font-weight:bold'>return</span><span style='color:#000000;background:#cceeee'> </span><span style='color:#200080;background:#cceeee;font-weight:bold'>false</span><span style='color:#406080;background:#cceeee'>;</span><span style='color:#000000;background:#cceeee'></span>
<span style='color:#406080;background:#cceeee'>}</span><span style='color:#000000;background:#cceeee'></span>
</pre>
<p>最後提供<a href="http://blog.wabow.com/wp-content/uploads/2009/08/nospamnx_090827.zip">範例程式下載</a>，分為一般 POST 與 AJAX 二種方式。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/2072/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Washop] 用 Word 合併列印 7-11 取貨標籤</title>
		<link>http://blog.wabow.com/archives/1986</link>
		<comments>http://blog.wabow.com/archives/1986#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:42:23 +0000</pubDate>
		<dc:creator>suzy</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[washop]]></category>
		<category><![CDATA[word]]></category>
		<category><![CDATA[合併列印]]></category>
		<category><![CDATA[標籤列印]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1986</guid>
		<description><![CDATA[今天要介紹的是 如何用 MS Office Word 的 合併列印 列出 相關訂單資料 及 條碼(barcode), 然後再用 標籤貼紙 印出來, 格式必須要符合 7-11 取貨的規則. 這個功能將會整合在 Washop 的訂單出貨功能. 其實就是一些很簡單的操作步驟, 但是摸索的過程也花了一些時間, 所以就紀錄下來, 供大家參考. 標籤貼紙是為了直接貼在包裹上, 讓出貨流程更有效率. 我們選A4大小的標籤貼紙, 市面上有販售各式各樣的規格. 1. 合併列印精靈: 郵件 -&#62; 啟動合併列印 -&#62; 逐步合併列印精靈 選取文件類型, 請選擇 "標籤" 2. 定訂標籤的格式 7-11 規定, 每張貼紙大小必須至少8cmX8cm, 依照A4的大小(210X297mm), 我們決定用 2欄 X 3列 來劃分, 每小格為 9.9cmX10.5cm 紙匣, 請選擇 "預設紙匣(自動選取)". 註: [...]]]></description>
			<content:encoded><![CDATA[<p>今天要介紹的是 如何用 MS Office Word 的 合併列印 列出 相關訂單資料 及 條碼(barcode), 然後再用 標籤貼紙 印出來, 格式必須要符合 7-11 取貨的規則. 這個功能將會整合在 Washop 的訂單出貨功能.<br />
其實就是一些很簡單的操作步驟, 但是摸索的過程也花了一些時間, 所以就紀錄下來, 供大家參考.</p>
<p><span id="more-1986"></span><br />
標籤貼紙是為了直接貼在包裹上, 讓出貨流程更有效率.<br />
我們選A4大小的標籤貼紙, 市面上有販售<a href="http://store.pchome.com.tw/2b/S027339.htm">各式各樣的規格</a>.</p>
<h3>1. 合併列印精靈:</h3>
<p>郵件 -&gt; 啟動合併列印 -&gt; 逐步合併列印精靈<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word1.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word1.jpg" alt="word1" width="444" height="398" class="alignnone size-full wp-image-1994" /></a></p>
<p>選取文件類型, 請選擇 "標籤"<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word2.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word2.jpg" alt="word2" width="360" height="375" class="alignnone size-full wp-image-1995" /></a></p>
<h3>2. 定訂標籤的格式</h3>
<p>7-11 規定, 每張貼紙大小必須至少8cmX8cm, 依照A4的大小(210X297mm), 我們決定用 <a href="http://store.pchome.com.tw/2b/M00467147.htm">2欄 X 3列</a> 來劃分, 每小格為 9.9cmX10.5cm</p>
<p>紙匣, 請選擇 "預設紙匣(自動選取)". 註: 它預設是 "手動送紙器", 如果沒修改此項, 在列印時會變成要手動塞紙到印表機喔!<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word3.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word3.jpg" alt="word3" width="500" class="alignnone size-full wp-image-1996" /></a></p>
<p>標籤編號, 請選擇 "自訂標籤", 請依照圖中所示, 輸入標籤的規格.<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word4.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word4.jpg" alt="word4" width="500" class="alignnone size-full wp-image-1997" /></a></p>
<h3>3. 匯出資料</h3>
<p>由 Washop 後台生成 CSV 訂單資料<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word5.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word5.jpg" alt="word5" width="504" height="376" class="alignnone size-full wp-image-1999" /></a></p>
<p>範例資料顯示如下:<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word6.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word6.jpg" alt="word6" width="500" class="alignnone size-full wp-image-2000" /></a></p>
<h3>4. 合併列印</h3>
<p>選取收件者, "使用現有清單".<br />
瀏覽, 請選取剛剛匯出的 CSV 檔. 直接按確定即可.<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word7.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word7.jpg" alt="word7" width="332" height="360" class="alignnone size-full wp-image-2002" /></a></p>
<h3>5. 編輯第一個標籤內容</h3>
<p>所有內容置中, 用標楷體（如何顯示條碼請見第九）<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word8.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word8.jpg" alt="word8" width="476" height="441" class="alignnone size-full wp-image-2004" /></a></p>
<h3>6. 安排標籤</h3>
<p>點選其他項目, 手動插入欄位<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word9.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word9.jpg" alt="word9" width="490" height="470" class="alignnone size-full wp-image-2005" /></a></p>
<p>完成後按 "更新所有標籤", 神奇的事就發生了<br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/word10.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word10.jpg" alt="word10" width="500" class="alignnone size-full wp-image-2006" /></a></p>
<h3>7. 預覽標籤</h3>
<p><a href="http://blog.wabow.com/wp-content/uploads/2009/08/word11.jpg"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/word11.jpg" alt="word11" width="500" class="alignnone size-full wp-image-2007" /></a></p>
<h3>8. 完成, 列印, 大功告成</h3>
<p><a href='http://blog.wabow.com/wp-content/uploads/2009/08/文件1.pdf'>列印結果範例</a><br />
印出來後可試著用條碼機試刷, 如果有聽到 B 的一聲, 那恭喜你, 成功啦. (灑花 <img src="http://blog.wabow.com/wp-content/uploads/2009/08/1775465354.jpg.gif" /></p>
<h3>9. 關於 條碼(barcode)</h3>
<ul>
<li>條碼是39碼, 規定前後都要加 *</li>
<li>條碼字型 <a href="http://www.barcodesinc.com/free-barcode-font/">可在此下載</a>.</li>
<li>條碼字體的大小: 我是設 34, 字元比例: 72%. 這樣才能保持在規定的 寬 = 7cm-7.5cm, 高 = 大於0.8cm 之間.
<li>如果條碼一直刷不過, 試試看條碼後面空一格, 空格轉成別的字型, 因為我們家的印表機印出來會把換行當作條碼印 (螢幕顯示正常, 印出來就不對了).</li>
<li>要用雷射印表機印, 條碼機才能感應.</li>
</ul>
<p>謝謝收看 <img src="http://blog.wabow.com/wp-content/uploads/2009/08/escape.gif" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1986/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[jQuery Plugin]抓取YouTube影片的截圖 jYouTube</title>
		<link>http://blog.wabow.com/archives/1985</link>
		<comments>http://blog.wabow.com/archives/1985#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:38:13 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1985</guid>
		<description><![CDATA[官方網站 http://jquery-howto.blogspot.com/2009/05/jyoutube-jquery-youtube-thumbnail.html js下載點 http://plugins.jquery.com/files/jyuotube.zip 介紹 YouTube(http://www.youtube.com/)是一個非常知名的影像網站，影片瀏覽起來速度還蠻快的，也因此很多網站在想要顯示影片時，都會連到這個網站。作法上有很多種，假使我們今天希望在自己的網站放置某個YouTube影片的截圖，然後點截圖才連到YouTube網站去瀏覽影片，這個截圖的動作有沒有比較簡單的做法呢?jQuery的Plugin--jYouTube提供了很簡單就可以達到目的的方法，讓我們來看看要怎麼處理吧! 程式碼 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 small : use video URL&#60;br /&#62; &#60;img src='' id='img1'&#62;&#60;br /&#62; big : use video ID &#60;br /&#62; &#60;img src='' id='img2'&#62; &#160; &#60;script type=&#34;text/javascript&#34; src=&#34;jquery-1.2.6.min.js&#34;&#62;&#60;/script&#62; &#60;script type=&#34;text/javascript&#34; src=&#34;jyuotube.js&#34;&#62;&#60;/script&#62; &#60;script [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.wabow.com/wp-content/uploads/2009/08/sample.JPG" alt="sample" width="331" height="379" class="aligncenter size-full wp-image-2025" /><br />
官方網站  <a href="http://jquery-howto.blogspot.com/2009/05/jyoutube-jquery-youtube-thumbnail.html">http://jquery-howto.blogspot.com/2009/05/jyoutube-jquery-youtube-thumbnail.html</a><br />
js下載點  <a href="http://plugins.jquery.com/files/jyuotube.zip">http://plugins.jquery.com/files/jyuotube.zip</a><br />
<span id="more-1985"></span></p>
<h3>介紹</h3>
<p>YouTube(<a href="http://www.youtube.com/">http://www.youtube.com/</a>)是一個非常知名的影像網站，影片瀏覽起來速度還蠻快的，也因此很多網站在想要顯示影片時，都會連到這個網站。作法上有很多種，假使我們今天希望在自己的網站放置某個YouTube影片的截圖，然後點截圖才連到YouTube網站去瀏覽影片，這個截圖的動作有沒有比較簡單的做法呢?jQuery的Plugin--jYouTube提供了很簡單就可以達到目的的方法，讓我們來看看要怎麼處理吧!</p>
<h3>程式碼</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;">small : use video URL<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">''</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'img1'</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
big   : use video ID <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">''</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'img2'</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery-1.2.6.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jyuotube.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
&nbsp;
$(function(){
&nbsp;
    var imgSrc = $.jYoutube('http://www.youtube.com/watch?v=hPzNl6NKAG0', 'small');
    var imgSrc2 = $.jYoutube('hPzNl6NKAG0');
&nbsp;
	$('#img1').attr('src',imgSrc);
	$('#img2').attr('src',imgSrc2);
&nbsp;
})
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></td></tr></table></div>

<h3>解說</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery-1.2.6.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jyuotube.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></td></tr></table></div>

<p>這兩行是載入必要的js。</p>
<p>jYouTube的寫法很簡單，如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">jYoutube</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'hPzNl6NKAG0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//指定YouTube的影片ID後回傳一個大的截圖網址</span>
$.<span style="color: #660066;">jYoutube</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://www.youtube.com/watch?v=hPzNl6NKAG0'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'small'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//指定YouTube的影片網址後回傳一個小的截圖網址</span></pre></td></tr></table></div>

<p>也就說，jYoutube會使用到兩個參數，第一個參數你可以設定為YouTube的影片ID(如:hPzNl6NKAG0)或是YouTube的影片網址(如:http://www.youtube.com/watch?v=hPzNl6NKAG0)；第二個參數則是希望顯示的截圖大小，如果保留空白則顯示較大的截圖，相對的如果輸入small則顯示小的截圖。實際顯示的效果可參照本文開頭的範例圖。</p>
<h3>總結</h3>
<p>jYouTube提供了很簡單就能取得YouTube影片的截圖，在需要大量引用時比用printscreen來的快速，提供給大家做個參考。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1985/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Open Flash Chart] 無痛繪製統計圖表</title>
		<link>http://blog.wabow.com/archives/1984</link>
		<comments>http://blog.wabow.com/archives/1984#comments</comments>
		<pubDate>Thu, 20 Aug 2009 06:21:07 +0000</pubDate>
		<dc:creator>abu</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1984</guid>
		<description><![CDATA[電子商務網站的後台，統籌管理了一堆訂單相關資訊，相對的，客戶對於產品銷售部份，若能搭配上統計圖表，更是一目了然，為了簡易製作出方便快速又美麗的成品，就是借重Open Flash Chart力量的時候.... 在官網上可以看到各式各樣的圖表，不管是長條圖、曲線圖、圓餅圖等等，都只要把統計數值拋給他，就會產生出美美的圖表， 首先必須先下載library 點我，解壓縮後丟到你的專案裡面，找個地方擺好 接著在你要輸出的樣板裡面，加上這堆↓ swfobject.embedSWF(&#34;自訂解壓縮路徑/open-flash-chart.swf&#34;, &#34;chart1&#34;, &#34;800&#34;, &#34;500&#34;, &#34;9.0.0&#34;, &#34;expressInstall.swf&#34;, {&#34;data-file&#34;:&#34;預定產生資料程式&#34;} ); 請依照專案狀況修改上述中文部份，就完成了畫面產生部份設定。 接著是資料產生部份，還記得上面剛填寫的"預定產生資料程式"嗎，就是準備編輯他，以下是部份主要程式的範例： include(&#34;自訂解壓縮路徑/php-ofc-library/open-flash-chart.php&#34;); // 載入 $chart = new open_flash_chart(); $title = new title($product-&#62;name.'三個月內銷售狀況'); $chart-&#62;set_title( $title ); $x = new x_axis(); $x-&#62;set_colour( 'gray' ); $x-&#62;set_grid_colour( '#86BF83' ); $y = new y_axis(); $y-&#62;set_range( 0, 1000, 100); $chart-&#62;set_y_axis( $y ); $bar = new [...]]]></description>
			<content:encoded><![CDATA[<p>電子商務網站的後台，統籌管理了一堆訂單相關資訊，相對的，客戶對於產品銷售部份，若能搭配上統計圖表，更是一目了然，為了簡易製作出方便快速又美麗的成品，就是借重Open Flash Chart力量的時候....</p>
<p><span id="more-1984"></span></p>
<p>在<a href="http://ofc.net23.net/">官網</a>上可以看到各式各樣的圖表，不管是長條圖、曲線圖、圓餅圖等等，都只要把統計數值拋給他，就會產生出美美的圖表，</p>
<p>首先必須先下載library <a href="http://sourceforge.net/projects/openflashchart/files/open-flash-chart/1.9.7/open-flash-chart-1.9.7.zip/download" />點我</a>，解壓縮後丟到你的專案裡面，找個地方擺好</p>
<p>接著在你要輸出的樣板裡面，加上這堆↓</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">swfobject.embedSWF(&quot;自訂解壓縮路徑/open-flash-chart.swf&quot;, &quot;chart1&quot;, &quot;800&quot;, &quot;500&quot;, &quot;9.0.0&quot;, &quot;expressInstall.swf&quot;,	{&quot;data-file&quot;:&quot;預定產生資料程式&quot;} );</pre></div></div>

<p>請依照專案狀況修改上述中文部份，就完成了畫面產生部份設定。</p>
<p>接著是資料產生部份，還記得上面剛填寫的"預定產生資料程式"嗎，就是準備編輯他，以下是部份主要程式的範例：</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">include(&quot;自訂解壓縮路徑/php-ofc-library/open-flash-chart.php&quot;); // 載入
$chart = new open_flash_chart();
$title = new title($product-&gt;name.'三個月內銷售狀況');
$chart-&gt;set_title( $title );
$x = new x_axis();
$x-&gt;set_colour( 'gray' );
$x-&gt;set_grid_colour( '#86BF83' );
$y = new y_axis();
$y-&gt;set_range( 0, 1000, 100);
$chart-&gt;set_y_axis( $y );
$bar = new bar();
$output  = new Array('1','2','3');
$bar-&gt;set_values( $outpu ); // 欲輸出的資料陣列 
$t = new tooltip( 'Hello<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">br</span>&gt;</span>val = #val#' );
$t-&gt;set_shadow( true );
$t-&gt;set_stroke( 5 );
$t-&gt;set_colour( &quot;gray&quot; );
$t-&gt;set_background_colour( &quot;#FFFFFF&quot; );
$t-&gt;set_title_style( &quot;{font-size: 14px; color: #000000;}&quot; );
$t-&gt;set_body_style( &quot;{font-size: 14px;  color: #000000;}&quot; );
$chart-&gt;add_element( $bar );
$chart-&gt;set_tooltip( $t );
echo $chart-&gt;toPrettyString();</pre></div></div>

<p>這邊只是簡易說明，詳細內容官網都可以查到，&amp; 範例也是一大堆，修改一下就能輕鬆呈現你要的樣式~ 算是很方便的圖表繪製外掛，感謝作者。  m（＿ ＿）m </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1984/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[分享] 垃圾留言判斷，隱藏驗證碼的 NoSpamNX class</title>
		<link>http://blog.wabow.com/archives/1974</link>
		<comments>http://blog.wabow.com/archives/1974#comments</comments>
		<pubDate>Thu, 20 Aug 2009 05:06:42 +0000</pubDate>
		<dc:creator>daniel</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[NoSpamNX]]></category>
		<category><![CDATA[垃圾留言]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1974</guid>
		<description><![CDATA[目前大部分網站在表單發送時，判斷機器人發送廣告、垃圾留言的方法是採用 CAPTCHA 的方式；然而如同之前在部落格上分享過的文章所述，額外的驗證碼機制反而造成使用者在參予留言或討論時望之卻步。同篇文章中也提到 WordPress 用來防治垃圾留言的 Plugin NoSpamNX；最近剛好客戶有阻擋垃圾留言的需求，所以就稍微研究了一下，順便改成 class 讓使用上能更具彈性。 基本的流程是在建構式中，將隨機產生的隱藏驗證碼存入 SESSION，同時利用這些值建立隨機順序的 HTML 碼，在使用者 POST 的時候加以驗證。 首先要在網頁的最上面先開啟 SESSION，並建立 NoSpamNX 物件，同時寫入 SESSION，產生 HTML 碼 // 啟動 SESSION session_start&#40;&#41;; &#160; // 載入 NoSpamNX class include_once&#40;'NoSpamNX.php'&#41;; // 建立物件時可以指定 SESSION 的名稱，或不輸入使用預設值 $noSpamNX = new NoSpamNX&#40;'test_for_NoSpamNX'&#41;; &#160; // 產生隨機順序的隱藏欄位 $hidden_fields_for_NoSpamNX = $noSpamNX-&#62;addHiddenFields&#40;&#41;; 將 HTML 碼嵌入表單中 echo $hidden_fields_for_NoSpamNX; 在送出表單後，根據： 1. 檢查 POST [...]]]></description>
			<content:encoded><![CDATA[<p>目前大部分網站在表單發送時，判斷機器人發送廣告、垃圾留言的方法是採用 <a href="http://zh.wikipedia.org/w/index.php?title=CAPTCHA&amp;variant=zh-tw" target="_blank">CAPTCHA</a> 的方式；然而如同之前在<a href="http://blog.wabow.com/archives/713" target="_blank">部落格上分享過的文章</a>所述，額外的驗證碼機制反而造成使用者在參予留言或討論時望之卻步。同篇文章中也提到 <a href="http://zh.wikipedia.org/w/index.php?title=WordPress&amp;variant=zh-tw" target="_blank">WordPress</a> 用來防治垃圾留言的 Plugin <a href="http://www.svenkubiak.de/nospamnx/" target="_blank">NoSpamNX</a>；最近剛好客戶有阻擋垃圾留言的需求，所以就稍微研究了一下，順便改成 class 讓使用上能更具彈性。<br />
<span id="more-1974"></span><br />
<a href="http://blog.wabow.com/wp-content/uploads/2009/08/nospamnx_class949.png"></a><a href="http://blog.wabow.com/wp-content/uploads/2009/08/nospamnx_class949.png"><img class="aligncenter size-large wp-image-1975" src="http://blog.wabow.com/wp-content/uploads/2009/08/nospamnx_class949-500x303.png" alt="nospamnx_class949" width="500" height="303" /></a><br />
基本的流程是在建構式中，將隨機產生的隱藏驗證碼存入 SESSION，同時利用這些值建立隨機順序的 HTML 碼，在使用者 POST 的時候加以驗證。</p>
<p>首先要在網頁的最上面先開啟 SESSION，並建立 NoSpamNX 物件，同時寫入 SESSION，產生 HTML 碼</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// 啟動 SESSION</span>
<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 載入 NoSpamNX class</span>
<span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'NoSpamNX.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// 建立物件時可以指定 SESSION 的名稱，或不輸入使用預設值</span>
<span style="color: #000088;">$noSpamNX</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> NoSpamNX<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test_for_NoSpamNX'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 產生隨機順序的隱藏欄位</span>
<span style="color: #000088;">$hidden_fields_for_NoSpamNX</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$noSpamNX</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addHiddenFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>將 HTML 碼嵌入表單中</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$hidden_fields_for_NoSpamNX</span><span style="color: #339933;">;</span></pre></div></div>

<p>在送出表單後，根據：</p>
<blockquote><p>1. 檢查 POST 過來的資料中，是否有 'nospamnx-1' 產生的 MD5 Name；不存在=機器人<br />
2. 檢查 POST 過來的 'nospamnx-1' MD5 Name，其值是否為零；不為零=機器人<br />
3. 檢查 POST 過來的資料中，是否有 'nospamnx-2' 產生的 MD5 Name；不存在=機器人<br />
4. 檢查 POST 過來的 'nospamnx-2' MD5 Name，其值是否為 SESSION 中 'nospamnx-2' MD5 Value；不相等=機器人</p></blockquote>
<p>每次通過檢查後就會清空 SESSION，所以每一個留言所使用的隱藏驗證碼都是不一樣的。</p>
<p>距離之前介紹 NoSpamNX，已經有一段時間；而作者在新版加入了選擇性的 <a href="http://zh.wikipedia.org/zh-tw/HTTP_referrer" target="_blank">HTTP referrer</a> 判斷。不過因為難免會造成誤判的情況，以及程式寫起來有點醜（誤）等種種原因，所以並沒有放在這次的 class 裡面。</p>
<p>最後關於範例程式下載，請參考《<a href="http://blog.wabow.com/archives/2072" target="_blank">[分享] 垃圾留言判斷，隱藏驗證碼的 NoSpamNX class PART2</a>》。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1974/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[PHP] 瞭解 static 關鍵字</title>
		<link>http://blog.wabow.com/archives/1972</link>
		<comments>http://blog.wabow.com/archives/1972#comments</comments>
		<pubDate>Wed, 19 Aug 2009 02:48:26 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1972</guid>
		<description><![CDATA[本文轉載自：[PHP] 瞭解 static 關鍵字 先前同事詢問有關 PHP static 關鍵字的用法，這裡我簡單整理一下。 static 主要用途在於定義一個變數空間，讓函式或類別可以保留住該變數的值，直到下次的存取。 以下就各別來探討 static 在函式與類別中的用法。 函式裡的 static 關鍵字 先來看看以下的例子： function getCount&#40;&#41; &#123; static $count = 0; $count ++; return $count; &#125; &#160; for &#40;$i = 0; $i &#60; 10; $i ++&#41; &#123; echo getCount&#40;&#41;, &#34;\n&#34;; &#125; &#160; /* output: 1 2 3 4 5 6 7 8 [...]]]></description>
			<content:encoded><![CDATA[<p>本文轉載自：<a href="http://www.jaceju.net/blog/?p=670">[PHP] 瞭解 static 關鍵字</a></p>
<p>先前同事詢問有關 PHP static 關鍵字的用法，這裡我簡單整理一下。</p>
<p>static 主要用途在於定義一個變數空間，讓函式或類別可以保留住該變數的值，直到下次的存取。</p>
<p>以下就各別來探討 static 在函式與類別中的用法。</p>
<p><span id="more-1972"></span></p>
<h2>函式裡的 static 關鍵字</h2>
<p>先來看看以下的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getCount<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    static <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$count</span> <span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$count</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">echo</span> getCount<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* output:
1
2
3
4
5
6
7
8
9
10
*/</span></pre></div></div>

<p>首先我們在 getCount() 這個方法中定義了一個 static 變數 $count ，然後每次呼叫 getCount() 時，就會對 $count 作累加的動作。</p>
<p>接著我們透過迴圈執行十次 getCount() 方法，便可得到了 1 ~ 10 的輸出結果。</p>
<p>這是因為將變數宣告為 static 後，第一次呼叫 getCount() 這個方法時，會為 $count 保留一塊記憶體空間；而當脫離了 getCount() 的變數作用域後，這個記憶體空間並不會被消滅掉，而會在下一次呼叫 getCount() 方法時，再次被配置進來，並還原先前的變數值。</p>
<p>因此，除了第一次呼叫 getCount() 方法外，接下來的每次呼叫都會讓 $count 值累加，而得到 1 ~ 10 的輸出結果；如果把 static 關鍵字拿掉，就會輸出十次的 1 。</p>
<h2>應用在遞迴上的 static 關鍵字</h2>
<p>瞭解函式中的 static 關鍵字用法後，我們來看一個應用的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fibV1<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> fibV1<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> fibV1<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>這是 PHP 版的 Fibonacci Sequence 遞迴函式，原理我就不多說明了。先來看看它在參數為 20 時所需要的執行時間：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$start_time</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> fibV1<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$end_time</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Spent Time: &quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$end_time</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start_time</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;(s)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* output:
6765
Spent Time: 0.26100397109985(s)
*/</span></pre></div></div>

<p>這裡代入的數字越大，執行時間會越長。</p>
<p>現在我們用 static 關鍵字來改寫：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fibV2<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    static <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> fibV2<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> fibV2<span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>然後再來看執行的時間：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$start_time</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> fibV2<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$end_time</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Spent Time: &quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$end_time</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start_time</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;(s)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* output:
6765&lt;br /&gt;Spent Time: 0.0009009838104248(s)
*/</span></pre></div></div>

<p>速度竟然差了快三百倍！為什麼？</p>
<p>其實是因為這裡的 static 關鍵字扮演了 cache 的角色，讓程式不用重新計算已經算好的結果。而使用了 static 關鍵字後，也使得執行時間不會再隨著代入數字變大而變長。</p>
<p class="note">註：不是任何遞迴函式都可以用 static 變數來做 cache ，在使用上要特別注意這一點。</p>
<h2>類別裡的 static 關鍵字</h2>
<p>在類別裡的 static 關鍵字，也扮演了類似的角色。我們利用 static 在類別裡定義的屬性，會佔用類別的記憶體空間。而透過同一類別所生成的物件，會彼此共享這個 static 屬性；所以不論我們產生多少同類別的物件，它們都會存取到同一個 static 類別屬性。</p>
<p>來看看以下的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> DB
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000088;">$_instance</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000088;">$_instanceCount</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$_instanceCount</span> <span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$_instance</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$_instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$_instance</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getInstanceCount<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$_instanceCount</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$db1</span> <span style="color: #339933;">=</span> DB<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$db1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstanceCount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1</span>
<span style="color: #000088;">$db2</span> <span style="color: #339933;">=</span> DB<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$db2</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstanceCount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1</span></pre></div></div>

<p>範例即為經典的 Singleton 模式，原理這裡先不多做說明。</p>
<p>這裡我們定義了兩個類別 static 屬性，分別是 $_instance 及 $_instanceCount ；而透過 static 定義的類別屬性，在類別裡存取時要用 self 關鍵字加上雙冒號 (::) ，例如 self::$_instance 。</p>
<p>接著我們可以看到在 getInstance() 方法中，如果 self::$_instance 是 null 的話，表示是第一次呼叫，那麼程式就會透過私有的建構式產生一個 DB 物件指定給 self::$_instance 變數，最後再將它回傳出去。這時雖然 getInstance() 裡的變數作用域已經結束，但 self::$_instance 卻會保留下來。</p>
<p>下一次 getInstance() 呼叫時，因為 self::$_instance 已經不再是 null 值，所以就會直接將其內容回傳給呼叫的程式了。</p>
<p>也因為這個原因，所以整個程式執行下來， DB 的 __construct() 方法也只被執行過一次，使得 self::$_instanceCount 也只累加一次，其結果永遠為 1 。</p>
<h2>結論</h2>
<p>一般 PHP 開發者很少會去使用 static 關鍵字，因為平常會用到 static 的場合其實也不多。這裡我再做一次 static 使用時機的重點整理：</p>
<ol>
<li>需要記住上一次函式執行的結果。</li>
<li>某些可以保留執行結果的遞迴函式。</li>
<li>不希望因為物件個體不同，進而被影響的類別屬性。</li>
<li>類別的 Singleton 模式。</li>
</ol>
<p>希望透過上面的說明，能讓大家對 static 關鍵字有進一步的瞭解。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1972/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>建立簡易的線上影片播放系統</title>
		<link>http://blog.wabow.com/archives/1964</link>
		<comments>http://blog.wabow.com/archives/1964#comments</comments>
		<pubDate>Thu, 13 Aug 2009 07:45:28 +0000</pubDate>
		<dc:creator>jaceju</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/archives/1964</guid>
		<description><![CDATA[最近有個小需求是要建立一個簡單的線上影片播放系統，不需要太複雜，只要能播放 FLV 即可。 本文就來為大家介紹一些免費的製作工具，包含轉檔以及播放；不需要有複雜的伺服端環境，也不會有麻煩的設定。 註：如果有線上自動轉檔這方面的需求，建議使用 YouTube API ，或參考 FFmpeg 來架設線上轉檔系統。 軟體下載 我們會用到以下兩個軟體與套件： Riva FLV Encoder ： FLV 轉檔轉體。 Flowplayer ：線上播放影片。 轉檔 其實就是照著介面操作： 在來源檔案的部份，我們可以選擇 FFmpeg 所支援的各種影片類型檔案。 然後轉完檔案後，再把轉好的 flv 檔放在網頁可以存取的地方。 嵌入影片 嵌入影片的方法也很簡單，首先把 Flowplayer 下載回來的 JavaScript 和 Flash 檔案放在適當的地方，然後在 HTML 中載入 JavaScript 即可。 接著利用一個 A 標籤，將連結指向我們的 flv 影片檔；最後再利用 Flowplayer 的指令來載入 Flash 播放器，並將播放位址指向剛剛的連結即可。 &#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 [...]]]></description>
			<content:encoded><![CDATA[<p>最近有個小需求是要建立一個簡單的線上影片播放系統，不需要太複雜，只要能播放 FLV 即可。</p>
<p>本文就來為大家介紹一些免費的製作工具，包含轉檔以及播放；不需要有複雜的伺服端環境，也不會有麻煩的設定。</p>
<p class="note">註：如果有線上自動轉檔這方面的需求，建議使用 <a href="http://code.google.com/intl/zh-TW/apis/youtube/overview.html" target="_blank">YouTube API</a> ，或參考 <a href="http://ffmpeg.org/" target="_blank">FFmpeg</a> 來架設線上轉檔系統。</p>
<p><span id="more-1964"></span></p>
<h2>軟體下載</h2>
<p>我們會用到以下兩個軟體與套件：</p>
<ul>
<li><a href="http://rivavx.com/?encoder">Riva FLV Encoder</a><strong> ：</strong> FLV 轉檔轉體。</li>
<li><a href="http://flowplayer.org/">Flowplayer</a> ：線上播放影片。</li>
</ul>
<h2>轉檔</h2>
<p>其實就是照著介面操作：</p>
<p><a href="http://blog.wabow.com/wp-content/uploads/2009/08/riva_encoder.png"><img src="http://blog.wabow.com/wp-content/uploads/2009/08/riva_encoder.png" alt="Riva FLV Encoder" /></a></p>
<p>在來源檔案的部份，我們可以選擇 FFmpeg 所支援的各種影片類型檔案。</p>
<p>然後轉完檔案後，再把轉好的 flv 檔放在網頁可以存取的地方。</p>
<h2>嵌入影片</h2>
<p>嵌入影片的方法也很簡單，首先把 <a href="http://flowplayer.org/">Flowplayer</a> 下載回來的 JavaScript 和 Flash 檔案放在適當的地方，然後在 HTML 中載入 JavaScript 即可。</p>
<p>接著利用一個 A 標籤，將連結指向我們的 flv 影片檔；最後再利用 Flowplayer 的指令來載入 Flash 播放器，並將播放位址指向剛剛的連結即可。</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=utf-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>線上影片播放範例<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;js/flowplayer.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;video/golfers.flv&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:block;width:480px;height:325px;&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;player&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
flowplayer(&quot;player&quot;, &quot;./swf/flowplayer.swf&quot;);
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></div></div>

<p>當然這樣的方案就顯得簡單很多，所以只適合在客戶影片不多，而且較不常更新的專案上使用。不過這個方案還有一個很明顯的缺點，那就是影片是公開的。這時如果需要影片不公開，就需要透過伺服端技術來下載位址做一些特別的處理。</p>
<p>完畢收工，謝謝收看。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1964/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Wacow] 使用Gmail SMTP發信</title>
		<link>http://blog.wabow.com/archives/1958</link>
		<comments>http://blog.wabow.com/archives/1958#comments</comments>
		<pubDate>Thu, 13 Aug 2009 06:43:49 +0000</pubDate>
		<dc:creator>abu</dc:creator>
				<category><![CDATA[技術分享]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1958</guid>
		<description><![CDATA[嘗試在wacow framework，使用gmail smtp發信，不過怎麼設定都一直錯誤， 拜讀咕狗大神之後，發現必須使用ssl連線， 於是開始搜尋wacow controller裡面Mailer的來源，為了測試方便，就不做靈活的改寫，直接硬來， 找到 path\wacow\app\lib\Wacow\Mail\PHPMailer.php，加上 public function setGoogle(){ $this-&#62;_mailer-&#62;SetLanguage(&#34;tw&#34;,'Wacow/vendor/PHPMailer//language/'); $this-&#62;_mailer-&#62;Mailer = &#34;smtp&#34;; $this-&#62;_mailer-&#62;CharSet = 'BIG5'; $this-&#62;_mailer-&#62;ContentType = &#34;text/html&#34;; $this-&#62;_mailer-&#62;Mailer = &#34;smtp&#34;; $this-&#62;_mailer-&#62;CharSet = 'BIG5'; $this-&#62;_mailer-&#62;ContentType = &#34;text/html&#34;; &#160; $this-&#62;_mailer-&#62;SMTPAuth = true; $this-&#62;_mailer-&#62;SMTPSecure = &#34;ssl&#34;; $this-&#62;_mailer-&#62;Host = &#34;smtp.gmail.com&#34;; $this-&#62;_mailer-&#62;Port = 465; &#160; $this-&#62;_mailer-&#62;Username = &#34;填上gmail帳號&#34;; $this-&#62;_mailer-&#62;Password = &#34;填上gmail密碼&#34;; } 接著在path\wacow\app\base\Mailer.php的send函式裡面，找到『 $result = $this-&#62;_mailer-&#62;send(); [...]]]></description>
			<content:encoded><![CDATA[<p>嘗試在wacow framework，使用gmail smtp發信，不過怎麼設定都一直錯誤，<span id="more-1958"></span></p>
<p>拜讀咕狗大神之後，發現必須使用ssl連線，</p>
<p>於是開始搜尋wacow controller裡面Mailer的來源，為了測試方便，就不做靈活的改寫，直接硬來，</p>
<p>找到 path\wacow\app\lib\Wacow\Mail\PHPMailer.php，加上</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">public function setGoogle(){
	$this-&gt;_mailer-&gt;SetLanguage(&quot;tw&quot;,'Wacow/vendor/PHPMailer//language/');
	$this-&gt;_mailer-&gt;Mailer = &quot;smtp&quot;;
	$this-&gt;_mailer-&gt;CharSet = 'BIG5';
	$this-&gt;_mailer-&gt;ContentType = &quot;text/html&quot;;
	$this-&gt;_mailer-&gt;Mailer = &quot;smtp&quot;;
	$this-&gt;_mailer-&gt;CharSet = 'BIG5';
	$this-&gt;_mailer-&gt;ContentType = &quot;text/html&quot;;
&nbsp;
	$this-&gt;_mailer-&gt;SMTPAuth   = true;
	$this-&gt;_mailer-&gt;SMTPSecure = &quot;ssl&quot;;
	$this-&gt;_mailer-&gt;Host       = &quot;smtp.gmail.com&quot;;
	$this-&gt;_mailer-&gt;Port       = 465;                   
&nbsp;
	$this-&gt;_mailer-&gt;Username   = &quot;填上gmail帳號&quot;;
	$this-&gt;_mailer-&gt;Password   = &quot;填上gmail密碼&quot;;
}</pre></div></div>

<p>接著在path\wacow\app\base\Mailer.php的send函式裡面，找到『 $result = $this-&gt;_mailer-&gt;send(); 』，在他之前任意位置加上</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">$this-&gt;_mailer-&gt;setGoogle();</pre></div></div>

<p>最後到controller測試一下，隨便找個action召喚Mailer出來</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">$mailer = new Mailer();
(略)
$mailer-&gt;send('咕狗SMTP測試', 'abu@wabow.com')</pre></div></div>

<p>接著就會在信箱內看到剛寄發的mail，重點是PHPMailer提供的SMTPSecure屬性，要記得設為"ssl"，不過好像要更新到XX版之後才有，測試報告結束。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1958/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[system]如何在Linux中把某個user加入群組 Howto: Linux Add User To Group</title>
		<link>http://blog.wabow.com/archives/1948</link>
		<comments>http://blog.wabow.com/archives/1948#comments</comments>
		<pubDate>Thu, 13 Aug 2009 04:24:04 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1948</guid>
		<description><![CDATA[前言 在linux的系統中，user與group有著密不可分的關係。透過兩者間的權限設定而達到在操作linux系統上一層又一層緊密且安全的防護。 那麼，要如何針對user去指定其群組呢，讓我們來看以下的說明。 如何新增一個帳號並同時指定主群組(primary group) 在linux作業系統中，要增加一個使用者也就是新增一個帳號我們一般會下以下指令； useradd username 所以增加一個andrew帳號就是︰ # useradd andrew 那麼，如果要新增一個帳號同時指定這個帳號的主群組(primary group)該如何下指令呢?如下︰ useradd -g {group-name} username 所以新增一個叫做andrew的帳號並同時指定andrew的主群組為rd則輸入︰ # useradd -g rd andrew 這裡要注意rd這個群組必須是已存在的，要確認rd群組是否存在可以下指令︰ # grep rd /etc/group 如果沒有任何資訊被顯示出來的表示rd群組並不存在，新增rd群組的指令如下︰ # groupadd rd 如此我們就成功新增了使用者andrew並同時指定他的主群組為rd。 如何新增一個帳號並同時指定副群組(secondary group) 那麼，假使我們要新增一個帳號並同時指定他的副群組又該如何設定呢？指令如下︰ useradd -G {group-name} username 這裡一樣要注意要加入的群組本身必須是已存在的。所以總結來說，當useradd後面接的選項是小寫的g就是加入主群組，大寫的G就是加入副群組。 如果要一次加入數個副群組舉例來說如下︰ # useradd -G admins,www,rd daniel 這裡表示新增一個叫daniel的帳號，並同時把此帳號加入admins、www、rd這幾個群組裡，也就是把要加入的數個群組用逗號串接起來即可。 修改已存在帳號的群組 前兩段都是針對新增帳號的群組所做的說明，那麼如果我們想要修改某個已存在的帳號的主群組和增加副群組呢？這裡用到usermod這個指令，修改主群組指令如下︰ # usermod -g admins [...]]]></description>
			<content:encoded><![CDATA[<p><H3>前言</H3></p>
<p>在linux的系統中，user與group有著密不可分的關係。透過兩者間的權限設定而達到在操作linux系統上一層又一層緊密且安全的防護。<br />
那麼，要如何針對user去指定其群組呢，讓我們來看以下的說明。  <span id="more-1948"></span></p>
<p><H3>如何新增一個帳號並同時指定主群組(primary group)</H3></p>
<p>在linux作業系統中，要增加一個使用者也就是新增一個帳號我們一般會下以下指令；</p>
<blockquote><p>useradd username</p></blockquote>
<p>所以增加一個andrew帳號就是︰</p>
<blockquote><p># useradd andrew</p></blockquote>
<p>那麼，如果要新增一個帳號同時指定這個帳號的主群組(primary group)該如何下指令呢?如下︰</p>
<blockquote><p>useradd -g {group-name} username</p></blockquote>
<p>所以新增一個叫做andrew的帳號並同時指定andrew的主群組為rd則輸入︰</p>
<blockquote><p># useradd -g rd andrew</p></blockquote>
<p>這裡要注意rd這個群組必須是已存在的，要確認rd群組是否存在可以下指令︰</p>
<blockquote><p># grep rd /etc/group</p></blockquote>
<p>如果沒有任何資訊被顯示出來的表示rd群組並不存在，新增rd群組的指令如下︰</p>
<blockquote><p># groupadd rd</p></blockquote>
<p>如此我們就成功新增了使用者andrew並同時指定他的主群組為rd。</p>
<p><H3>如何新增一個帳號並同時指定副群組(secondary group)</H3></p>
<p>那麼，假使我們要新增一個帳號並同時指定他的副群組又該如何設定呢？指令如下︰</p>
<blockquote><p>useradd -G {group-name} username</p></blockquote>
<p>這裡一樣要注意要加入的群組本身必須是已存在的。所以總結來說，當useradd後面接的選項是小寫的g就是加入主群組，大寫的G就是加入副群組。<br />
如果要一次加入數個副群組舉例來說如下︰</p>
<blockquote><p># useradd -G admins,www,rd daniel</p></blockquote>
<p>這裡表示新增一個叫daniel的帳號，並同時把此帳號加入admins、www、rd這幾個群組裡，也就是把要加入的數個群組用逗號串接起來即可。</p>
<p><H3>修改已存在帳號的群組</H3></p>
<p>前兩段都是針對新增帳號的群組所做的說明，那麼如果我們想要修改某個已存在的帳號的主群組和增加副群組呢？這裡用到usermod這個指令，修改主群組指令如下︰</p>
<blockquote><p># usermod -g admins andrew</p></blockquote>
<p>這裡表示我們要把andrew這個帳號的主群組修改為admins。而以下指令︰</p>
<blockquote><p># usermod -a -G ftp daniel</p></blockquote>
<p>則表示我們把daniel這個帳號加入到ftp這個群組。</p>
<p><H3>參考網址</H3></p>
<p><a href="http://www.cyberciti.biz/faq/howto-linux-add-user-to-group/">http://www.cyberciti.biz/faq/howto-linux-add-user-to-group/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1948/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>全型轉半型</title>
		<link>http://blog.wabow.com/archives/1874</link>
		<comments>http://blog.wabow.com/archives/1874#comments</comments>
		<pubDate>Thu, 13 Aug 2009 04:08:11 +0000</pubDate>
		<dc:creator>suzy</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[big5]]></category>
		<category><![CDATA[encode]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1874</guid>
		<description><![CDATA[今天想要分享的是 中文字 全型轉半型的 function! 之前的做法很土法鍊鋼, 就是笨笨地用取代(str_replace)的方式把所有全型字一一換成半型字, 但是客戶經常回報, 某些特定字會造成亂碼, 像是 '中央北路' and '郭郭' 等.... 造成了許多困擾. 因此上網搜尋了一下, 且找到了一個真正的解決方法....... 出處: [原创]PHP全角转半角算法和函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function fullToHalf&#40;$str, $encode='Big5'&#41; &#123; if [...]]]></description>
			<content:encoded><![CDATA[<p>今天想要分享的是 中文字 全型轉半型的 function!</p>
<p>之前的做法很土法鍊鋼, 就是笨笨地用取代(str_replace)的方式把所有全型字一一換成半型字, 但是客戶經常回報, 某些特定字會造成亂碼, 像是 '中央北路' and '郭郭' 等.... 造成了許多困擾.</p>
<p>因此上網搜尋了一下, 且找到了一個真正的解決方法.......</p>
<p><span id="more-1874"></span></p>
<p>出處:  <a href="http://p.dvbbs.net/rwb7p1i40004.shtml">[原创]PHP全角转半角算法和函数</a></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fullToHalf<span style="color: #009900;">&#40;</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span> <span style="color: #000088;">$encode</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'Big5'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$encode</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">'UTF8'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mb_convert_encoding</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$encode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$ret</span><span style="color: #339933;">=</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$str</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000088;">$s1</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$str</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// 判斷 $c 第八位是否為 1 (漢字）</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">=</span><span style="color: #990000;">ord</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$s1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x80</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
			<span style="color: #000088;">$s2</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$str</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">++</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$s3</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$str</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">++</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xF</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">12</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ord</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$s2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3F</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">ord</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$s3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3F</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">12288</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$ret</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">' '</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">65280</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$c</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">65375</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$c</span> <span style="color: #339933;">-=</span> <span style="color: #cc66cc;">65248</span><span style="color: #339933;">;</span>
				<span style="color: #000088;">$ret</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$ret</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$s1</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$s2</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$s3</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$ret</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$str</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$encode</span><span style="color: #339933;">==</span> <span style="color: #0000ff;">'UTF-8'</span> ? <span style="color: #000088;">$ret</span> <span style="color: #339933;">:</span> <span style="color: #990000;">mb_convert_encoding</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ret</span><span style="color: #339933;">,</span> <span style="color: #000088;">$encode</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>研究了一下寫法, 複習了一下 <a href="http://us3.php.net/manual/en/language.operators.bitwise.php">Bitwise Operators (位元運算)</a></p>
<ul>
<li> &lt;&lt; - Shift left (means "multiply by two")</li>
<li> &amp;  - And </li>
<li> | - Or (inclusive or) </li>
</ul>
<h2>程式裡有0x的為16進位數:</h2>
<ul>
<li>0x80 = 16 * 8 = 128 = 10000000</li>
<li>0xF = 15 = 1111</li>
<li>0x3F = 3 * 16 + 15 = 48 + 15 = 63 (也可以從 ASCII table 找）</li>
</ul>
<h2>全型與半型:</h2>
<ul>
<li>半型字符範圍：33-126</li>
<li>全型字符範圍：65281-65374</li>
<li>對應關係是相差：65248</li>
<li>全型空格：12288</li>
<li>半型空格：32</li>
</ul>
<h2>心得</h2>
<p>這個function還真好用阿 XD, 又可順便複習一下 Bitwise, 雖然我們很少用到, 但它其實還有很多活用空間唷.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1874/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[RegExp] 正規表示式簡介</title>
		<link>http://blog.wabow.com/archives/1875</link>
		<comments>http://blog.wabow.com/archives/1875#comments</comments>
		<pubDate>Thu, 13 Aug 2009 03:22:50 +0000</pubDate>
		<dc:creator>daniel</dc:creator>
				<category><![CDATA[技術分享]]></category>
		<category><![CDATA[Regular Expression]]></category>
		<category><![CDATA[正規表示式]]></category>

		<guid isPermaLink="false">http://blog.wabow.com/?p=1875</guid>
		<description><![CDATA[回顧前二次測試先行的作業，都有使用到大家在輸入字串判斷上的好朋友；所以這次就來介紹一下囉！正規表示式，Regular Expression。它有多種翻譯名稱：正規式、正規表示法、正則表達式...等等，就連英文縮寫也有多種稱呼；總之只要是用來描述或者匹配一系列符合某個句法規則的字元串的單個字元串，就被稱為正規表示式。它經常被用來檢查使用者所輸入的資料是否符合規則，像是 E-mail 或是電話號碼之類，有著一定規則的字串。 一開始接觸正規表示式的時候，真的覺得他是程式界的火星文，猛然一看幾乎無法分辨這些由符號構成的字串到底有什麼涵義，也很難想像它在驗證字串的能力上是如此驚人！如今正規表示式已被許多程式語言廣泛運用，甚至不少文字編輯器也提供支援。相關的使用規則 Wiki 解釋的非常清楚，之前曾經推薦過的「正則表達式30分鐘入門教程」by deerchao 更是深入淺出；雖然不太可能真的在 30 分鐘內完全了解，但是關於正規表示式的各種應用，作者都巨細靡遺的搭配實例一一解說，非常用心。在碰到難解的規則時，重新看過一遍會有另一番體認唷！ 最後分享一個之前寫的正規表示式測試程式，原本是用單頁的 PHP 做處理，現在結合 jQuery Form Plugin 達到不需換頁的效果。在測試正規規則是否正確時，是不錯的小幫手唷！ P.S 其實 Regular Expression Library 也有提供類似的服務 RETester，不過還是在本機上執行比較快速囉^^ 正規表示式測試程式下載]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.wabow.com/wp-content/uploads/2009/08/tbq9YRzNVjmi5kluDwHoNiWIo1_400.jpg"><img class="alignleft size-medium wp-image-1876" src="http://blog.wabow.com/wp-content/uploads/2009/08/tbq9YRzNVjmi5kluDwHoNiWIo1_400-228x300.jpg" alt="tbq9YRzNVjmi5kluDwHoNiWIo1_400" width="228" height="300" /></a>回顧前二次<a href="http://blog.wabow.com/archives/tag/%E6%B8%AC%E8%A9%A6%E5%85%88%E8%A1%8C" target="_blank">測試先行</a>的作業，都有使用到大家在輸入字串判斷上的好朋友；所以這次就來介紹一下囉！<a href="http://zh.wikipedia.org/w/index.php?title=%E6%AD%A3%E8%A6%8F%E5%BC%8F&amp;variant=zh-tw" target="_blank">正規表示式</a>，Regular Expression。它有多種翻譯名稱：正規式、正規表示法、正則表達式...等等，就連英文縮寫也有多種稱呼；總之只要是用來描述或者匹配一系列符合某個句法規則的字元串的單個字元串，就被稱為正規表示式。它經常被用來檢查使用者所輸入的資料是否符合規則，像是 E-mail 或是電話號碼之類，有著一定規則的字串。</p>
<p>一開始接觸正規表示式的時候，真的覺得他是程式界的<a href="http://zh.wikipedia.org/w/index.php?title=%E7%81%AB%E6%98%9F%E6%96%87&amp;variant=zh-tw" target="_blank">火星文</a>，猛然一看幾乎無法分辨這些由符號構成的字串到底有什麼涵義，也很難想像它在驗證字串的能力上是如此驚人！如今正規表示式已被許多程式語言廣泛運用，甚至不少文字編輯器也提供支援。相關的使用規則 Wiki 解釋的非常清楚，之前曾經推薦過的「<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm" target="_blank">正則表達式30分鐘入門教程</a>」by deerchao 更是深入淺出；雖然不太可能真的在 30 分鐘內完全了解，但是關於正規表示式的各種應用，作者都巨細靡遺的搭配實例一一解說，非常用心。在碰到難解的規則時，重新看過一遍會有另一番體認唷！</p>
<p><span id="more-1875"></span>最後分享一個之前寫的正規表示式測試程式，原本是用單頁的 PHP 做處理，現在結合<a href="http://malsup.com/jquery/form/" target="_blank"> jQuery Form Plugin</a> 達到不需換頁的效果。在測試正規規則是否正確時，是不錯的小幫手唷！</p>
<p>P.S 其實 <a href="http://regexlib.com/" target="_blank">Regular Expression Library</a> 也有提供類似的服務 <a href="http://regexlib.com/RETester.aspx" target="_blank">RETester</a>，不過還是在本機上執行比較快速囉^^</p>
<p><a href="http://blog.wabow.com/wp-content/uploads/2009/08/regexp.zip">正規表示式測試程式下載</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.wabow.com/archives/1875/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

