2009年10月31日

PHP中用Socket發送電子郵件

在作者所申請的幾個PHP 主頁空間中,能夠提供mail功能的實在不多,總是調用完mail()函數之後就毫無下文了。

但是電子郵件在網上生活中的作用越來越大作用我不想再說了,但是如果主頁空間不支持mail()發送那麼怎麼辦呢?我也想過通過socket來實現郵件 發送,但無奈對用php 進行socket編程不熟悉,再加上發送郵件要用到SMTP協議,又要讀不少的英文了,所以一直也沒有去研究過。

終於有一天我發現了一篇文章,關於用socket編程發送郵件。我如獲至寶般將其拷貝下來,並且將其改造成了一個php可用的類,供大家使用。

原來的文章只是一個簡單的例子,而且還有一些錯誤,在我經過多次的實驗、改造終於將其改成了一個直接使用socket,向指定的郵箱發送郵件的類,如果大家和前面關於發送MIME的文章結合起來,就可以實現在不支持mail()函數的網站上發送郵件了。

因為發送郵件的過程需要時間,可能與mail()的處理機制還不完全一樣,所以速度要慢一些,但是可以解決需要發送郵件功能的燃眉之急,同時你也可以學習用php 進行socket編程。下面就將這個類的實現原理介紹給大家,同時向大家講解一些關於SMTP的基本知識。

Socket編程介紹

向大家申明,本人不是一個TCP/IP編程專家,故在此只是講出了我的一點理解和體會;使用fsockopen函數打開一個Internet連接,函數語法格式:

int fsockopen(string hostname, int port, int [errno], string [errstr], int [timeout]);

參數的意思我想不用講了,這裡由於要使用SMTP協議,所以端口號為25。在打開連接成功後,會返回一個socket句柄,使用它就可以像使用文件句柄一樣的。可使用的操作有fputs(),fgets(),feof(),fclose()等,很簡單地介紹就到這裡吧。

SMTP的基礎

基於TCP/IP的因特網協議一般的命令格式都是通過請求/ 應答方式實現的,採用的都是文本信息,所以處理起來要容易一些。SMTP是簡單郵件傳輸協議的簡稱,它可以實現客戶端向服務器發送郵件的功能。

所以下面所講的命令是指客戶端向服務器發出請求指令,而響應則是指服務器返回給客戶端的信息;SMTP分為命令頭和信息體兩部分。命令頭主要完成客戶端與服務器的連接,驗證等。整個過程由多條命令組成。每個命令發到服務器後,由服務器給出響應信息,一般為3 位數字的響應碼和響應文本。不同的服務器返回的響應碼是遵守協議的,但是響應正文本則不必。每個命令及響應的最後都有一個回車符,這樣使用fputs()和fgets()就可以進行命令與響應的處理了。SMTP的命令及響應信息都是單行的。信息體蚴怯始?的正文部分,最後的結束行應以單獨的"."作為結束行。

客戶端一些常用的SMTP指令為:

HELO hostname: 與服務器打招呼並告知客戶端使用的機器名字,可以隨便填寫
MAIL FROM: sender_id : 告訴服務器發信人的地址
RCPT TO: receiver_id : 告訴服務器收信人的地址
DATA : 下面開始傳輸信件內容,且最後要以只含有.的特殊行結束
RESET: 取消剛才的指令,從新開始
VERIFY userid: 校驗帳號是否存在(此指令為可選指令,服務器可能不支持)
QUIT : 退出連接,結束

服務器返回的響應信息為(格式為:響應碼+空格+解釋):

220 服務就緒(在socket連接成功時,會返回此信息)
221 正在處理
250 請求郵件動作正確,完成(HELO,MAIL FROM,RCPT TO,QUIT指令執行成功會返回此信息)
354 開始發送數據,結束以 .(DATA指令執行成功會返回此信息,客戶端應發送信息)
500 語法錯誤,命令不能識別
550 命令不能執行,郵箱無效
552 中斷處理:用戶超出文件空間

下面給出一個簡單的命令頭(這是在打開socket之後做的),是我向stmp.263.net發郵件的測試結果:

HELO limodou
250 smtp.263.net
MAIL FROM: [email protected]
250 Ok
RCPT TO: [email protected]
250 Ok
DATA
354 End data with .
To: [email protected]
From: [email protected]
Subject: test
From: [email protected]
test
.
QUIT
250 Ok: queued as C46411C5097E0

這就是一些SMTP的簡單知識。相關內容可以查閱RFC。
RFC 821定義了收/發電子郵件的相關指令。
RFC 822則制定了郵件內容的格式。
RFC 2045-2048制定了多媒體郵件內容的格式,
RFC 1113, 1422-1424則是討論如何增進電子郵件的保密性。


send_mail類的實現

現在開始介紹我所編寫的發送郵件類。有了上面的預備知識了,下面就是實現了。

類的成員變量

var $lastmessage; //記錄最後返回的響應信息
var $lastact; //最後的動作,字符串形式
var $welcome; //用在HELO後面,歡迎用戶
var $debug; //是否顯示調試信息
var $smtp; //smtp服務器
var $port; //smtp端口號
var $fp; //socket句柄

其中,$lastmessage和$lastact用於記錄最後一次響應信息及執行的命令,當出錯時,用戶可以使用它們。為了測試需要,我還定義了$debug變量,當其值為true時,會在運行過程中顯示一些執行信息,否則無任何輸出。$fp用於保存打開後的socket句柄。

類的構造
--------------------------------------------------------------------------------
function send_mail($smtp, $welcome="", $debug=false)
{
if(empty($smtp)) die("SMTP cannt be NULL!");
$this->smtp=$smtp;
if(empty($welcome))
{
$this->welcome=gethostbyaddr("localhost");
}
else
$this->welcome=$welcome;
$this->debug=$debug;
$this->lastmessage="";
$this->lastact="";
$this->port="25";
}
--------------------------------------------------------------------------------
這個構造函數主要完成一些初始值的判定及設置。$welcome用於HELO指令中,告訴服務器用戶的名字;HELO指令要求為機器名,但是不用也可以。如果用戶沒有給出$welcome,則自動查找本地的機器名。

顯示調試信息
--------------------------------------------------------------------------------
1 function show_debug($message, $inout)
2 {
3 if ($this->debug)
4 {
5 if($inout=="in") //響應信息
6 {
7 $m='<< ';
8 }
9 else
10 $m='>> ';
11 if(!ereg("\n$", $message))
12 $message .= "";
13 $message=nl2br($message);
14 echo "${m}${message}";
15 }
16 }
--------------------------------------------------------------------------------
這個函數用來顯示調試信息。可以在$inout中指定是上傳的指令還是返回的響應,如果為上傳指令,則使用"out";如果為返回的響應則使用"in"。

第3行,判斷是否要輸出調試信息。

第5行,判斷是否為響應信息,如果是,則在第7行將信息的前面加上"<< "來區別信息;否則在第10行加上">> "來區別上傳指令。

第11-12行,判斷信息串最後是否為換行符,如不是則加上HTML換行標記。第13行將所以的換行符轉成HTML的換行標記。

第14行,輸出整條信息,同時將信息顏色置為灰色以示區別。

執行一個命令
--------------------------------------------------------------------------------
1 function do_command($command, $code)
2 {
3 $this->lastact=$command;
4 $this->show_debug($this->lastact, "out");
5 fputs ( $this->fp, $this->lastact );
6 $this->lastmessage = fgets ( $this->fp, 512 );
7 $this->show_debug($this->lastmessage, "in");
8 if(!ereg("^$code", $this->lastmessage))
9 {
10 return false;
11 }
12 else
13 return true;
14 }
--------------------------------------------------------------------------------
在編寫socket處理部分發現,一些命令的處理很相似,如HELO,MAIL FROM,RCPT TO,QUIT,DATA命令,都要求根據是否顯示調試信息將相關內容顯示出來,同時對於返回的響應碼,如果是期望的,則應繼續處理,如果不是期望的,則應中斷出理。所以為了清晰與簡化,專門對這些命令的處理編寫了一個通用處理函數。函數的參數中$code為期望的響應碼,如果響應碼與之相同則表示處理成功,否則出錯。

第3行,記錄最後執行命令。

第4行,將上傳命令顯示出來。

第5行,則使用fputs真正向服務器傳換指令。

第6行,從服務器接收響應信息將放在最後響應消息變量中。

第7行,將響應信息顯示出來。

第8行,判斷響應信息是否期待的,如果是則第13行返回成功(true),否則在第10行返回失敗(false)。

這樣,這個函數一方面完成指令及信息的發送顯示功能,別一方面對返回的響應判斷郵件發送處理是否成功。

原文出處:http://calos-tw.blogspot.com/2009/09/phpsocket.html

Google 教你優化 PHP,PHP 開發團隊指內容不確

Google 的 webmaster Eric Higgins 寫了一篇文章介紹怎樣優化 PHP,文章刊登不久,PHP 開發團隊其中一員 Gwynne Raskind 發文提出異議,指 Eric 所說的與事實不符,有些甚至完全相反,在 PHP 5 上幾乎沒有一項 Eric 的優化技巧能帶來實質的好處。我們摘錄了比較具爭議性的幾點,看看誰是誰非。

Eric Higgins: 不要沒來由的複製變量

Eric 說每次我們複製一個變量的時候,便會消耗一些記憶體,一些 PHP 初哥為了使他們的原碼「好讀」,喜歡把一些預定義變量複製到另一個名稱比較簡短、容易記憶的變量,這樣對程式的效能有負面的影響。在下面的例子中,如果用戶輸入了一段 512KB 的文字,程式便會消耗 1MB 的記憶體:

$description = strip_tags($_POST['description']);
echo $description;

我們沒有理由把文字複製到 $description,只需:

echo strip_tags($_POST['description']);

Gwynne Raskind: 複製變量不一定增加記憶體的消耗

從 PHP 4 開始,Zend 引擎變使用一種稱為「copy-on-write」的記憶體管理技術,舉一個例子,無論我們把 $source 的內容複製多少次到 $destination,我們一天不改變 $source 的值,真正的複製都沒有進行,不論我們的程式讀取 $source 還是 $destination,都是從同一個記憶體地址提取內容。以下的例子可以測試複製變量對記憶體使用影響:

$data = str_repeat("*", 512 * 1024); // 模擬 512K 數據 $memory_used_before = memory_get_usage();
$more_data = $data;
$memory_used_after = memory_get_usage();
print "Before: {$memory_used_before}\nAfter: {$memory_used_after}\n";

在 PHP 5.3 (在除錯編譯模式下)執行的結果是:

Before: 853968
After: 854236

可見在複製前後記憶體的消耗相差只有 268 bytes,若果用正常的編譯模式,這也是絕大部分網站使用的模式,差別只有 64 bytes。

Eric Higgins: 字符串要用單引號

PHP 容許我們使用單引號或者雙引號來指定字符串,其實兩者的效能有很大差異,雙引號告訴 PHP 引擎在字符串中找尋變量,並以變量的值取代有關的部份,若果你有一列很長的純文字字符串,雙引號會引致效能降低。


Gwynne Raskind: 大部份情況下雙引號的效能比單引號高

對於不含變量的純文字字符串,由於 PHP 引擎的實作方式,雙引號的效能肯定比單引號高。若果字符串中的變量不算很多,使用雙引號並把變量內崁在字符串中,效能也比使用單引號和字符串連接運算子的方法高。

Eric Higgins: 使用 switch/case,不用 if/else

不論是為了效能、可讀性、還是可維護性,若果只對一個變量進行檢測,我們都應該盡量使用 switch/case 代替 if/else,例如以下使用 if/else 的原碼:

if($_POST['action'] == 'add') {
addUser();
}
elseif ($_POST['action'] == 'delete') {
deleteUser();
} elseif ($_POST['action'] == 'edit') {
editUser();
} else {
defaultAction();
}
 
應該改用 switch/case 重寫:

switch($_POST['action']) {
case 'add':
addUser();
break;
case 'delete':
deleteUser();
break;
case 'edit':
editUser();
break;
default:
defaultAction();
break;
}

Gwynne Raskind: switch/case 和 if/else 效能上沒有分別

Eric 的論點根本沒有根據,使用哪一種句式純粹是編程風格的問題,除了在極少數情況外,兩者的效能幾乎毫無分別。

Related Links
•Google 教你優化 PHP,PHP 開發團隊指內容不確
•Google 教你優化 PHP (原文)
•Gwynne Raskind 反對 Eric Higgins (原文)

十大技巧提升你的PHP實力

在 Smashing Magazine 的網站,Glen Stansberry 提出十個進階 PHP 技巧,可以即時提昇你的 PHP 編程實力,其中包括 SQL 注入攻擊的「作弊表」、簡化判斷句中的 else 部分、在不得已的情況下才使用正規表達式、三元運算子、Memcached 數據庫快取系統等等,以下是詳細的內容。

PHP 在 1995 年從一個不起眼的編程語言開始,多年來迅速發展,現在已經是其中一種最流行的網絡開發語言,許多熱門網站均採用 PHP 來開發,絕大多數的程式和網站項目都是由這種流行語言寫成。

由於 PHP 如此受歡迎,任何網站開發人員幾乎都不能不認識 PHP,這份教程是為那些剛剛完成了 PHP 的學習初階,捲起衣袖準備大幹一番的人,下面列出的十個優秀技巧,是 PHP 開發人員必須學習,並在每次編程時使用它們,這些提示可以加快你們對 PHP 的熟練,使程式碼跑得更快捷,更簡潔,性能上更優化。

1. 使用 SQL 注入攻擊作弊表

SQL 注入攻擊是一種非常令人厭惡的東西,它是一種安全漏洞,允許黑客利用程式碼中的漏洞潛入你的數據庫。雖然本文與 MySQL 無關,不過許多 PHP 程式使用 MySQL 數據庫,若果你要寫安全的程式碼,懂得什麼情況需要避開是很有用的。

Furruh Mavituna 寫了一篇很有趣的 SQL 注入攻擊作弊表,其中一章節有關 PHP 和 MySQL 的安全漏洞,若果你能避開其中所述的行為,你的程式將不容易受到攻擊。

2. 認識各種比較運算符的分別

比較運算符是 PHP 很重要的部份,可惜很多程序員並不熟悉它們之間的分別,事實上,據一篇在 IO Reader 網站上發表的文章,許多 PHP 開發人員不能分辨 PHP 各種比較運算符之間的差異,引用該文的幾句話:

這是極為重要的,但是很多 PHP 開發人員根本不知道 == 和 === 有什麼分別,從本質上講,== 判斷兩個值是否相等,PHP 在進行比較前會嘗試轉換數據類型以,例如:1== '1' (true);=== 則同時判斷值和數據類型,例如:1==='1'(false),開發人員必須儘快認識這些運算符對常用函式如 strpos() 的實用性,由於 PHP 把零視為「false」,沒有 === 的話我們無從知道一個被搜尋字符串是在一個較長字符串的開始位置,還是根本不存在,在很多其他應用裡,當傳回值為零未必等於 false 的時候,=== 便十分有用。

你可以到 PHP.net 網站看到各種比較運算符的清單。

3. 簡化判斷句中的 else 部分

必須提示各位,第三和第四點可能會使程式碼的可讀性降低,這兩點強調速度和效能,若果你不想犧牲程式碼的可讀性,你可能要跳過它們。

凡是能使程式碼更簡單和更小的做法,通常都是好的做法,其中之一就是把 else 敘述句的內容抽出來,Christian Montoya 便有一個很好的例子,利用較短的 else 敘述句來轉換字符。

常見的 else 敘述句:

if( this condition ){$x = 5;}else{$x = 10;}

如果 $x 的預設值是 10,我們便從 10 開始,無須在 else 部分指定它的值。

$x = 10;
if( this condition )
{
$x = 5;
}

if( this condition )如果(這種情況) {( $x = 5; $ x = 5 ; }) else其他的 { ( $x = 10; $ x = 10 ; } )

雖然看起來沒有很大分別,不過若果你的程式中有很多 else 敘述句,累加的效果會很明顯。

4. 放棄那些括號

就像簡化 else 敘述句那樣,如果在控制結構後只有一句表達式,放棄表達式前後的括號可以節省一些字符。Evolt.org 便有一個靈巧的例子示範怎樣減少使用括號。

if ($gollum == 'halfling') {$height --;} 這是相同的:
if ($gollum == 'halfling') $height --; 這個方法可以在程式中多次使用:
if ($gollum == 'halfling') $height --;else $height ++;
if ($frodo != 'dead') echo 'Gosh darnit, roll again Sauron';
foreach ($kill as $count) echo 'Legolas strikes again, that makes' . $count . 'for me!';

5. 取 str_replace(),捨 ereg_replace() 及 preg_replace()

以效率來說,str_replace() 比正規表達式更適合用來取代字符串,據一些研究,str_replace() 的效率比 ereg_replace() 和 preg_replace() 高 61%。

$x = 10; $ x = 10 ; if( this condition )如果(這種情況) { ( $x = 5; $ x = 5 ; } )


6. 使用三元運算符

在使用 if / else 敘述句的場合,使用三元運算符,PHP Value 網站有一個使用三元運算符的範例:

< ?php

//PHP COde Example usage for: Ternary Operator
$todo = (empty($_POST[’todo’])) ? ‘default’ : $_POST[’todo’];
// The above is identical to this if/else statement
if (empty($_POST[’todo’])) {
$action = ‘default’;
} else {
$action = $_POST[’todo’];
}
?>
三元運算符可以節省程式碼的空間,使你的程式碼沒那麼混亂,也使其更容易閱讀。但要注意,不要在同一句敘述句中使用超過一個三元運算符,因為在這種情況下 PHP 未必知道該怎麼辦。

7. Memcached

雖然 PHP 有很多數據庫快取工具,但是 Memcache 始終是效能最高的一個,雖然從實作的角度看它不是最簡單方便,不過若果你要建立一個使用數據庫的網站,Memcached 肯定可以為你的系統加速,Memcached 的快取架構最初是為一個以 PHP 為基礎的網誌系統 LiveJournal 而建立的,在 PHP.net 網站有一份安裝和使用 Memcached 的教學文件。

8. 使用開發架構

你未必每一個開發項目都使用 PHP 開發架構,但開發架構如 CakePHP、Zend、Symfony、CodeIgniter 等無疑可以大大減少你建立一個網站的時間。開發架構是一個包含很多常用功能的軟件,可以幫助加快開發工作,使用開發架構可以消除一些開發網頁應用系統和網頁服務的繁瑣工作。

如果你可以利用開發架構來處理重複性的編程工作,你的開發進度將會大幅提高,寫的程式碼越少,所需的調試和除蟲的工作便越少。

9. 正確使用壓抑運算符

錯誤壓抑運算符(在 PHP 手冊中稱為「錯誤控制運算符」)是指「@」符號,當它出現在一句 PHP 表達式前面,意思就是不論表達式發生任何錯誤都不要顯示出來,這是非常方便的,尤其是當你不知道程式碼什麼時候會發生錯誤,希望有關的錯誤訊息不會在用戶面前出現。

然而,很多程序員經常錯誤地使用這個錯誤壓抑運算符,「@」運算符相當緩慢,並且銷耗頗多資源,對系統的效能有負面影響。Michel Fortin 有一些很好的例子示範如何用替代方法迴避「@」運算符,以下是他使用 isset 替代錯誤壓抑運算符的範例:

if (isset($albus)) $albert = $albus;else $albert = NULL;
相當於:
$albert = @$albus;

第二種形式雖然比較簡單,但它的執行速度卻比第一種慢兩倍,一個更好的解決方法是透過參考來指定變量,不會引致任何錯誤訊息,像這樣:

$albert =& $albus;

必須注意這些變化都有某些副作用,只能應用在有極高效能要求的場合中使用。

10. 使用 isset 捨棄 strlen

如果你要檢查一個字符串是否過長,應該使用 isset 而不是 strlen,因為使用 isset 比 strlen 快五倍,還有,使用 isset 的話即使變量不存在你的表達式仍然是合法的,D-talk 有一個用 isset 替代 strlen 的詳細說明,例如要檢查字符串 $str 是否超過 9 個字符,使用 isset 的方法是:

if (isset($str[9])) echo "字符串的長度是 10 或以上"else echo "字符串的長度小於 10"雖然速度上這只是很小的改善,但加上前面涵蓋的技巧,累加起來便可以有更快、更精簡的程式。

相關資訊:http://www.hkpug.net/node/278

[好書推薦]Facebook與funP應用程式設計

Facebook與funP應用程式設計


















內容簡介
在全球瘋社交網站的狂潮下,您是不是已經在Facebook或funP這些社交網站中玩上了不少的應用程式呢?其實您也可以自己製作這些應用程式!本書是華文世界第一本教導如何在Facebook與funP網站上開發應用程式的工具書,從社交網路的概念、操作介面、架構、開發前的準備工作到應用程式的語法與物件,都將徹底剖析介紹。透過本書解說與實際範例的展示,製作出有趣的應用程式將不再是「非死不可」的夢想。

本書特色
全球最夯社交網站快速導覽。
Facebook操作介面與各項功能完整攻略。
認識本土社交網站funP所推出的funP麻吉社交平台。
瞭解Facebook與funP應用程式運作架構,與開發應用程式應注意的事項。
開發應用程式前的準備工作與網路資源大公開。
深入解析應用程式各項設定參數。
詳細剖析Facebook / funP API,呼叫社交網站中的各種功能不是問題。
FBML完整教學,揭露輕鬆開發應用程式的奧秘。
揭開FQL內幕,快速取得社交網站資料數據。
FBJS深入研究,瞭解Facebook/funP針對應用程式開發所提供的JavaScript解決方案。
綜合實例詳盡說明,實際瞭解打造應用程式的完整流程。


目錄
Chapter01、社交網站的簡介
Chapter02、認識Facebook
Chapter03、認識funP
Chapter04、Facebook與funP應用程式架構
Chapter05、開發前的準備工作
Chapter06、建立我們的應用程式
Chapter07、Facebook API
Chapter08、Facebook Markup Language (FBML)
Chapter09、Facebook Query Language (FQL)
Chapter10、Facebook Javascript (FBJS)
Chapter11、綜合實例

內容範例:







































2009年10月30日

[好書推薦]PHP for Flash FMS動態網站開發手札

PHP for Flash FMS動態網站開發手札


















本書核心內容
.與FMS(Flash Media Server)結合,讓PHP for Flash有聲有色,更加完整。
.採用最新的ActionScript3.0 API技術。
.新一代使用開放程式Zend_Amf、AMF PHP,以及社群推薦使用的SabreAMF,最貼近潮流與趨勢。
.透析Flash於網路上的安全核心,加強AMFPHP在對話及對應物件的安全性。
.理論與實務並重,用開發理論的闡述,佐以實際案例的開發,學習效果最佳!
.最符合中文環境的需求,各種中文處理的疑難雜症問題,這裡通通幫您解決!
.提供大量實用模組及範例,使用者可以輕鬆構建所要實現的程式,使得實用功能大大增強。

 
本書內容共分四大主題
第Ⅰ篇 PHP for Flash入門和基本原理篇
第Ⅱ篇 使用Flash Remoting加速應用程式開發
第Ⅲ篇 Flash即時通訊應用程式和FMS
第Ⅳ篇 模組、大規模應用、部署篇

採用最新Flash Remoting技術,搭配開放原碼,包括最新流行的Adobe官方支援Zend_Amf、大量使用的AMFPHP1.9和1.2,以及社群推薦使用的SabreAMF,當然,本書也沒有遺漏已經流行10多年的XML-RPC;並重點提示修改這些開放源碼以支援中文雙位元組,讓它們能完美應用到你的專案中。
介紹了多種通訊協定:AMF0/AMF3/XML/RTMP/RTMPT及提供大量實用的模組及範例,讓使用者可以輕鬆構建所要實現的程式,讓您的動態網站盡善盡美!

Flash設計師,可以藉由本書學習到更為進階的Flash應用技巧,加強功力;PHP程式設計師,也可以藉由本書學習到如何利用Flash來製作出界面更加華麗的應用程式。


本書附光碟
.各章程式及範例
.電子書
附件A 在ActionScript2.0程式中實現AMF-RPC存取
附件B AMF-RPC用戶端ActionScript2.0類庫API語法精講
附件C 特殊字元的URL編碼對照表
附件D 參考文獻以及資料來源

 
相關資訊:http://www.books.com.tw/exep/assp.php/yogo/exep/prod/booksfile.php?item=0010452410

PHP 程式效能優化的 40 條建議

  這裡有一篇 Tsung 轉載的「PHP 程式效能優化的 40 條建議」,覺得很不錯,例如使用 str_replace > preg_replace, 但是 strtr 又比 str_replace 快, $row['id'] 比 $row[id] 快 7 倍, 雖然有些龜毛了點, 偶爾注意一下也不錯,提供給有興趣的朋友參考一下。

原文: 40 Tips for optimizing your php code

轉載自翻譯: 優化PHP程式的40條建議

1.如果一個方法可靜態化,就對它做靜態聲明。速率可提升至4倍

2.echo 比 print 快

3.使用echo的多重參數(譯註:指用逗號而不是句點)代替字元串連接

4.在執行for循環之前確定最大循環數,不要每循環一次都計算最大值

5.註銷那些不用的變量尤其是大數組,以便釋放內存

6.盡量避免使用__get,__set,__autoload

7.require_once()代價昂貴

8.在包含文件時使用完整路徑,解析操作系統路徑所需的時間會更少

9.如果你想知道腳本開始執行(譯註:即服務器端收到客戶端請求)的時刻,使用$_SERVER['REQUEST_TIME']要好於time()

10.函數代替正則表達式完成相同功能

11.str_replace函數比preg_replace函數快,但strtr函數的效率是str_replace函數的四倍

12.如果一個字元串替換函數,可接受數組或字元作為參數,並且參數長度不太長,那麼可以考慮額外寫一段替換程式,使得每次傳遞參數是一個字元,而不是只寫一行程式接受數組作為查詢和替換的參數

13.使用選擇分支語句(譯註:即switch case)好於使用多個if,else if語句

14.用@屏蔽錯誤消息的做法非常慢

15.打開apache的mod_deflate模塊

16.資料庫連接當使用完畢時應關掉

17.$row['id']的效率是$row[id]的7倍

18.錯誤訊息代價昂貴

19.盡量不要在for循環中使用函數,比如for ($x=0; $x < count($array); $x)每循環一次都會調用count()函數

20.在function中遞增局部變量,速度是最快的。幾乎與在函數中調用局部變量的速度相當

21.遞增一個全局變量要比遞增一個局部變量慢2倍

22.遞增一個物件屬性(如:$this->prop++)要比遞增一個局部變量慢3倍

23.遞增一個未預定義的局部變量要比遞增一個預定義的局部變量慢9至10倍

24.僅定義一個局部變量而沒在函數中調用它,同樣會減慢速度(其程度相當於遞增一個局部變量)。PHP大概會檢查看是否存在全局變量

25.方法調用看來與類中定義的方法的數量無關,因為我(在測試方法之前和之後都)添加了10個方法,但性能上沒有變化

26.派生類中的方法運行起來要快於在基類中定義的同樣的方法

27.調用帶有一個參數的空函數,其花費的時間相當於執行7至8次的局部變量遞增操作。類似的方法調用所花費的時間接近於15次的局部變量遞增操作

28.用單引號代替雙引號來包含字元串,這樣做會更快一些。因為PHP會在雙引號包圍的字元串中搜尋變量,單引號則不會。當然,只有當你不需要在字元串中包含變量時才可以這麼做

29.輸出多個字元串時,用逗號代替句點來分隔字元串,速度更快。註:只有echo能這麼做,它是一種可以把多個字元串當作參數的“函數”(譯註:PHP手冊中說echo是語言結構,不是真正的函數,故把函數加上了雙引號)

30.Apache解析一個PHP腳本的時間要比解析一個靜態HTML頁面慢2至10倍。盡量多用靜態HTML頁面,少用腳本

31.除非腳本可以緩存,否則每次調用時都會重新編譯一次。引入一套PHP緩存機制通常可以提升25%至100%的性能,以免除編譯開銷

32.盡量做緩存,可使用memcached。memcached是一款高性能的內存物件緩存系統,可用來加速動態Web應用程式,減輕數據庫負載。對運算碼 (OP code)的緩存很有用,使得腳本不必為每個請求做重新編譯

33.當操作字元串並需要檢驗其長度是否滿足某種要求時,你想當然地會使用strlen()函數。此函數執行起來相當快,因為它不做任何計算,只返回在zval 結構(C的內置數據結構,用於存儲PHP變量)中存儲的已知字元串長度。但是,由於strlen()是函數,多多少少會有些慢,因為函數調用會經過諸多步驟,如字母小寫化(譯註:指函數名小寫化,PHP不區分函數名大小寫),會跟隨被調用的函數一起執行。在某些情況下,你可以使用isset() 技巧加速執行你的程式,舉例如下:

if (strlen($foo) < 5) { echo "Foo is too short"; }
與下面的技巧做比較:
if (!isset($foo{5})) { echo "Foo is too short"; }

調用isset()恰巧比strlen()快,因為與後者不同的是,isset()作為一種語言結構,意味著它的執行不需要函數查找和字母小寫化。也就是說,實際上在檢驗字元串長度的頂層程式中你沒有花太多開銷


34.當執行變數$i的遞增或遞減時,$i++會比++$i慢一些。這種差異是PHP特有的,並不適用於其他語言,所以請不要修改你的C或Java程式並指望它們能立即變快,沒用的。++$i更快是因為它只需要3條指令(opcodes),$i++則需要4條指令。後置遞增實際上會產生一個臨時變量,這個臨時變量隨後被遞增。而前置遞增直接在原值上遞增。這是最優化處理的一種,正如Zend的PHP優化器所作的那樣。牢記這個優化處理不失為一個好主意,因為並不是所有的指令優化器都會做同樣的優化處理,並且存在大量沒有裝配指令優化器的網際網路服務提供商(ISPs)和服務器

35.並不是所有都要使用OOP,面向物件往往開銷很大,每個方法和物件調用都會消耗很多Memory

36.並非要用 class 實現所有的數據結構,數組也很有用

37.不要把方法細分得過多,仔細想想你真正打算重用的是哪些程式?

38.當你需要時,你總能把程式分解成方法

39.盡量採用大量的PHP內置函數

40.如果在程式中存在大量耗時的函數,你可以考慮用C擴展的方式實現它們

41.評估檢驗(profile)你的程式。檢驗器會告訴你,程式的哪些部分消耗了多少時間。Xdebug調試器包含了檢驗程式,評估檢驗總體上可以顯示出程式的瓶頸

42.mod_zip可作為Apache模塊,用來即時壓縮你的數據,並可讓數據傳輸量降低80%

43.另一篇優化PHP的精彩文章,由John Lim撰寫

2009年10月29日

[PHP] 阿拉伯數字轉為大寫國字



最近YOGO在知識+看到這個問題常被問到的,剛好手邊之前有收集到相關的程式碼,就在此提供給有需要的朋友囉!! 

   1: <?php

















   2: function getChineseNumber($money){ 

















   3: $ar = array("零", "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖") ; 

















   4: $cName = array("", "", "拾", "佰", "仟", "萬", "拾", "佰", "仟", "億", "拾億", "佰億", "仟億"); 

















   5: $conver = ""; 

















   6: $cLast = "" ; 

















   7: $cZero = 0; 

















   8: $i = 0; 



































   9: for ($j = strlen($money) ; $j >=1 ; $j--){ 



































  10: $cNum = intval(substr($money, $i, 1)); 



































  11: $cunit = $cName[$j]; //取出位數 



































  12: if ($cNum == 0) { //判斷取出的數字是否為0,如果是0,則記錄共有幾0 



































  13: $cZero++; 



































  14: if (strpos($cunit,"萬億") >0 && ($cLast == "")){ // '如果取出的是萬,億,則位數以萬億來補 



































  15: $cLast = $cunit ; 



































  16: } 



































  17: }else { 



































  18: if ($cZero > 0) {// '如果取出的數字0有n個,則以零代替所有的0 



































  19: if (strpos("萬億", substr($conver, strlen($conver)-2)) >0) { 



































  20: $conver .= $cLast; //'如果最後一位不是億,萬,則最後一位補上"億萬" 



































  21: } 



































  22: $conver .= "零" ; 



































  23: $cZero = 0; 



































  24: $cLast = "" ; 



































  25: } 



































  26: $conver = $conver.$ar[$cNum].$cunit; // '如果取出的數字沒有0,則是中文數字+單位 



































  27: } 



































  28: $i++; 



































  29: } 



































  30: //'判斷數字的最後一位是否為0,如果最後一位為0,則把萬億補上 



































  31: if (strpos("萬億", substr($conver, strlen($conver)-2)) >0) { 



































  32: $conver .=$cLast; // '如果最後一位不是億,萬,則最後一位補上"億萬" 



































  33: }elseif(strlen($money)-1 == $cZero && $cZero >=5){



































  34: $conver .=$cName[5];



































  35: } 



































  36: return $conver; 



































  37: } 



































  38: ?>



















原文出處:http://www.neo.com.tw/archives/903





另外 [題目]php程式設計面試考試  阿拉伯數字轉成國字數字 這二篇文章有更多的解法,提供給有需要的朋友參考一下。







如果覺得這篇文章對您有所幫助,在觀看完文章之餘,希望能點選下方方廣告,當作是對YOGO的支持,讓YOGO更有寫作的動力。


















2009年10月27日

相對路徑與絕對路徑

之前在知識+回覆了一個問題「hinet空間上傳後無法開啟 20點」,其中有提到相對路徑與絕對路徑的問題,其中有一位網友說到:

當網站.網頁上傳至網際網路後沒有人還會把C:裡面的檔案當成網路上的路徑了.不管是絕對路徑或相對路徑.自己電腦裡的東西對於網際網路而言其實什麼都不是也沒有任何路徑關係.

假如網頁是放在自己電腦裡自己觀賞而已當然可以把自己電腦裡的檔案都以C:\...\....\檔名.副檔名當成網頁上檔案的路徑名稱.問題是既然網頁檔案都已經上傳至網際網路了還在討論C:裡的東西相對於網路上的網頁是絕對或相對路徑豈不可笑..即使是用自己電腦架伺服器也沒人會以C:來代表網際網路上該網頁與檔案的路徑關係.

任何一個檔案上傳至網際網路後就只有一個絕對路徑.全世界也沒有其他檔案路徑會跟它重複.這也就是所謂的檔案網址.
 
基本上YOGO不喜歡筆戰,但也借這個機會與各位朋友探討一下「何謂相對路徑與絕對路徑」,學網頁設計的朋友大部份應該都有去過「網站建置百寶箱」這個網站,其中有一篇「路徑表示法及SSI(上)】」寫的不錯,或是「鳥哥的 Linux 私房菜」「第七章、Linux 檔案與目錄管理」「1.1 相對路徑與絕對路徑」或是「HTML相對路徑(Relative Path)和絕對路徑(Absolute Path)」「講解 URL 結構與分享幾個相對路徑與絕對路徑的開發技巧 」這些都是寫的不錯的文章有興趣的朋友可以參考看看,其實就YOGO的認知來說 :
 
C:\web\folder\index.html

http://blog.yogo.tw/index.html
 
都屬於絕對路徑,或許有人會如上面的朋友所說"當網站.網頁上傳至網際網路後沒有人還會把C:裡面的檔案當成網路上的路徑了.不管是絕對路徑或相對路徑.自己電腦裡的東西對於網際網路而言其實什麼都不是也沒有任何路徑關係,即使是用自己電腦架伺服器也沒人會以C:來代表網際網路上該網頁與檔案的路徑關係."其實這部份並不全對,自架主機有時會,尤其是用PHP之類的網頁程式時會用到,就如這篇「Smarty 入門」文章中所寫的「第一個用Smarty寫的小程式」中的設定部份就會用到,而它這部份的設定是參考 XOOPS 的的設定。



另外關於上面的那位朋友再回覆中有提到"一般來說使用絕對路徑是不會出錯的.使用相對路徑才會容易出錯.雖然下載速度會差一點點但是人的視覺是感覺不出來的.",我想他所謂的「絕對路徑」應該是指「http://blog.yogo.tw/index.html 」這種路徑,其實YOGO是不建議使用他說的這種用法,原因有2:

1.缺少彈性及費時費功
以原提問者的內容他是使用Hinet提供的免費空間,除非它永遠都使用Hinet的網路,才能一直永久使用Hinet提供的免費空間,若有一天他覺得seednet的上網方案比較划算,改用seednet提供的免費空間,那它的圖片勢必跑不出來,有興趣者可以參考篇文章「8-2-2 相對路徑與絕對路徑」

2.速度較慢
就如上面那為朋友說的「速度會差一點點」,但他沒說原因,所以YOGO在此補充說明一下,若依照上面那位朋友對定義的絕對路徑為「http://blog.yogo.tw/index.html 」,因為「blog.yogo.tw」是網址,需透過「DNS的解析」才能知主機的正確位置,所以速度會比較慢(因為要等DNS的回應),再加上若查詢的DNS繁忙的話,反應速度會更慢,若有興趣的朋友可看一下下面文章。

DNS 的基本觀念
http://eservice.seed.net.tw/class/class08.html

DNS 的運作原理
http://eservice.seed.net.tw/class/class09.html


所以YOGO並不建議用上面那位朋友所定義的「絕對路徑」方式去設定,除非你有申請自己的網址,且確定域名永久不變,那使用這種方式倒也無妨,不過依然存在著DNS解析的速度問題;所以YOGO個人是建議最好是用「相對路徑」的方式會好一點;那麼上面朋友所說的「絕對路徑」方式不就完全沒有使用的地方?那倒也不是,像是透過MAIL發送的HTML圖文版的EDM或是交換連結,就需使用上面朋友所說的方式,圖片才能正常顯示。

至於YOGO所說的另一種「絕對路徑」(C:\web\folder\index.html),是需用在能解析PHP之類的網站主機上,至於為什麼要用這種路徑呢?優點有下面幾個:

1.避免引入的檔案位置錯誤
這裡有篇文章「require函數的問題」有興趣的朋友參考看看。

2.保護重要檔案不被下載
有時為了保護一些重要檔案不被下載,會在網頁根目錄之外另放一個資料夾,確保檔案不會被任意下載或WEB SERVER出錯時,目錄被任意瀏覽,導致重要檔案被下載。

有鑑於技術的進步,設計網頁很多人其實都不會HTLM語法,很多人都是用Dreamweaver之類的軟體來設計,但如果對這類軟體的操作若不熟,尤其是插入網頁根目錄之外的圖片,如



 
 
 
 
 
 
 
 
 
 
 
 
那這時路徑就會是 img src="file:///C /Users/YOGO/Pictures/6_648_0_1.jpg" width="373" height="342"
 

         
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  若將這個路徑存檔並上傳到網站空間圖一定跑不出來的,別以為這種事不可能發生,就YOGO回答網友的問題經驗來說,這種事的發生機率很高,有興趣的朋友也可參考一下這篇文章「絕對路徑與相對路徑」

以上是YOGO個人的一些小見解,若有任何意見歡迎提出來一起討論;題外話YOGO是個標準的霹靂布袋戲迷,想起上面那位朋友所說的問題是既然網頁檔案都已經上傳至網際網路了還在討論C:裡的東西相對於網路上的網頁是絕對或相對路徑豈不可笑。這段話後,讓YOGO想起劇中一個名叫「梅郎浦追昔」(http://drama.pili.com.tw/role/people.php?meng=meilang的角色開場詩:「少年無端愛令名,也無學術誤蒼生,白雲一笑懶如此,一遇天風吹便行。」,YOGO還真一度以為自己「不學無術、誤人子弟」,但YOGO認為有時候回答網友的問題,要將網友當初學者來看待,而不能以自身的程度來看網友提出的問題(雖然YOGO沒有什麼程度可言 > <),也或許有人會跟上面的網友一樣認為問題是既然網頁檔案都已經上傳至網際網路了還在討論C:裡的東西相對於網路上的網頁是絕對或相對路徑豈不可笑。,但別懷疑很多初學的網友圖片的路徑就是"C:\web\folder\01.jpg",然後就將檔案傳到web server上,這種事屢見不鮮,所以別以自己的角度看事情,該以自己當初是初學者的角度去看事情,這樣網友也會比較容易明白你所要表的東西,這是YOGO的一點小心得,與所有朋友分享一下吧^^。

延伸閱讀:[五分鐘教室] PHP 檔案引入路徑問題

如果覺得這篇文章對您有所幫助,在觀看完文章之餘,希望能點選下方方廣告,當作是對YOGO的支持,讓YOGO更有寫作的動力。



2009年10月25日

油價一直漲金價也跟著漲,這是最壞的時代也是投資保值最好的時代

  最近油價一直漲金價也跟著漲,這是最壞的時代也是投資保值最好的時代。

【優質的金】1兩-黃金條塊

【優質的金】1兩-黃金條塊

投資保值最佳利器 成色符合國際標準
千足純金(品質符合國際水準)!!!
此黃金條塊附英文純金成色卡!!!

商品規格
品牌:優質的金
顏色:金色
材質:千足純金(品質符合國際水準) 
金重:約10錢(1兩重)
尺寸:約2.0CM*1.5CM
商品數量:金條乙塊
附件:商品成色保證卡(英文)、商品成色保證卡(中文)

注意:
一、七天鑑賞期內退換貨請保持商品完整性,若有贈品、配件煩請一起退回,若有缺件、商品毀損不完整情況發生,恕無法退換貨
二、商品圖檔顏色因電腦螢幕設定差異會略有不同,以實際商品顏色為準,請見諒

相關資訊:http://partner.buy.yahoo.com.tw/pub/gotobuy.ashx?gdid=1724752&mcode=MV9FMWo0Mk43NjNDVFNaNUxMVGM1ZlhlQ2hrSjhhQTNHVkg0eG1XUE01WGFVPQ==


Manstyle 1兩黃金條塊

Manstyle 1兩黃金條塊

◎條塊都用來投資、保值工具,目前台灣市面上流通有數種品牌,皆由國外標進來,成份都符合國際標準。

◎若有此需求者,須預先訂購,並以當日金價(條塊價)為買賣基準。

商品規格
▉品牌: MANSTYLE
▉黃金成份:千足純金(品質符合國際水準)
▉金 重: 約1兩
▉附品質保證書(成色保証).

相關資訊:http://partner.buy.yahoo.com.tw/pub/gotobuy.ashx?gdid=1372074&mcode=MV9FMWo0Mk43NjNDVFNaNUxMVGM1ZlhlQ2hrSjhhQTNHVkg0eG1XUE01WGFVPQ==

2009年10月23日

[好書推薦]SEO網路大行銷

SEO網路大行銷




內容簡介




搜尋引擎優化關鍵 網站排名超躍進
.「關鍵字廣告」及「SEO搜尋引擎最佳化」搜尋引擎行銷方式介紹
.搜尋引擎發展的歷史、分類及工作原理
.搜尋引擎最佳化的每個基礎環節及操作技巧
.常用的搜尋引擎最佳化工具及使用方法
.結合搜尋引擎最佳化構建網站

本書是作者從事搜尋引擎優化的經驗總結,深度剖析搜尋引擎優化的每個細節,包括「關鍵字策略」、「URL最佳化」、「HTML最佳化」、「網頁結構」、「網站結構」及「連結策略」等。同時介紹搜索引擎優化技術,提高搜索引擎及使用者體驗友善度。
.對於搜尋引擎最佳化初學者,可瞭解搜尋引擎最佳化的各個基礎環節、實施流程及操作技巧。同時修正目前或曾經犯過的錯誤,以避免重蹈覆轍。
.對於具備一定搜尋引擎最佳化經驗的讀者,可以把本書的理論與自己的實務經驗相結合,於實務技術更加精進。
.對於網路行銷人員,本書可以幫助你們展開更好地搜尋引擎行銷工作。
.對於網站管理人員、網站設計製作者、網站運營策劃者、網站程式設計師等,本書可以幫助你們規劃出更好的網站,進一步提高網站的使用者及搜尋引擎友善度。
.本書可以作為各大專院校電子商務或電腦應用等專業的教材,讓學生掌握實用技能,提高競爭力。
本書適合SEO初學者以及具備一定經驗的讀者,是從事網站運營、網站策劃、網站推廣、網站設計、程式開發的人員的必備手冊。讀者並不需要具備程式開發的知識,但需要具備網頁製作能力及對HTML語言有一定程度的瞭解。

2009年10月11日

[好書推薦]NO.1暢銷作者最受歡迎的特效解密--Photoshop CS4

  這本書介紹很多很炫且實用的技巧,剛看時會覺得似乎很複雜、困難,但實作一遍之後會發覺其實並沒有想像中的難,是一本很值得推薦的Photoshop的好書。

NO.1暢銷作者最受歡迎的特效解密--Photoshop CS4


























內容簡介

創意點子 + 靈活技巧 = 酷炫特效
最火紅的Photoshop絕技與詢問度最高的酷炫特效大解密!

  《Photoshop User TV》節目主持人,全球No.1最暢銷Photoshop專書作者Scott Kelby又回來了!此次他將帶來令人瞠目結舌的最新特效,再次締造本書前一版榮登Photoshop暢銷專書的紀錄。

  Scott為《Photoshop User》雜誌總編輯、「全美Photoshop專業協會」會長、《Photoshop User TV》節目主持人,以及「Photoshop世界研討與展覽會」會議技術主席。Scott也是獲獎作者,著作包括《Photoshop CS4完美呈現》、《Scott Kelby’s 7-Point System for Adobe Photoshop CS3》和《The Digital Photography Book》第一、二冊等。他輕鬆、白話的教學風格讓Photoshop學習起來更加簡單、更富趣味,也贏得全球眾多讀者的喜愛。

  在這本書中你將學到在電視上、雜誌裡和網路上看到的,最機密的Photoshop CS4特效,透過Scott淺顯易懂,步驟明確的教學,搭配數百張全彩影像示範,所有做法將公諸於世。本書內容簡潔明瞭,容易上手,你將可以立刻開始製作這些特效:

  *最新的影像特效
  *如何模擬棚拍效果(保證令你驚奇)
  *最新的文字特效
  *最受電影歡迎的技巧
  *詢問度最高的廣告特效
  *客戶最愛的商業效果
  *最夯的網頁特效
  * Photoshop Extended最令人驚豔的3D特效
  *一卡車看似困難,但一旦解密之後其實很簡單的各種特效

  不僅如此,整本書也充滿了創意點子、版面編排和設計技巧,協助你展現自己的創造力。以上所有的內容都收錄在這本獨一無二的Photoshop專書裡,你一定會愛上它的!


相關資訊:http://www.books.com.tw/exep/assp.php/yogo/exep/prod/booksfile.php?item=0010449774

聖誕跑趴歡樂降★韓版假兩件針織連衣裙$890,新款顯瘦棒球服連帽風衣外套下殺$510,冬新款歐美棉襖棉服連帽短款外套限量↘$530,秋冬新款韓版大碼毛領氣質毛料外套↘$680,快上左耳貓網路購物

您好!如圖太小看不清楚,請 點選此處 看詳細內容 左耳貓蝦皮賣場 https://shopee.tw/hrf5168 左耳貓 露天賣場 http://class.ruten.com.tw/user/index00.php?s=starbox 左耳貓粉...