推文按鈕

收進你的MyShare個人書籤

2009年9月28日 星期一

PHP List API

PHPList 是一套很流行的電子報發送系統
但是如果想要從其他的web application叫用,有沒有好的方法呢?

在網路上找了一些資訊,好好來研究一下
http://forums.phplist.com/viewtopic.php?t=5009
http://forums.phplist.com/viewtopic.php?f=7&t=5009&start=15
http://forums.phplist.com/viewtopic.php?f=15&t=24734

PHP Command Docs
http://docs.phplist.com/CommandLineScriptInfo

2009年9月22日 星期二

[PHP] 輸出Excel/CSV檔

http://www.phpdc.com/article/18/
http://topic.csdn.net/t/20060824/16/4973156.html#

2009年9月18日 星期五

沒想到也遇到「許功蓋」的問題

最近幫朋友改網頁
她和本來合作的程式不合
因此整個網站臨時要找人幫忙收尾

所以我第一次有機會用php進行開發....
沒想到改到一半突然狂跳 "unexpected t-string in xxx"
查了一下,這個錯誤訊息應該是多餘的符號

但是檢查了好幾遍就是沒有多的分號或括號
搞了一整個禮拜

今天重新逐段註解,控制段落,後來又發現原來程式碼設定big5
想說是不是編輯器設定編碼的問題....但是無功而返
最後終於發現問題出現在我加了一行 "發送成功" 的字串;

"許" "功" "蓋" 三個字在 Big5下 會出現此問題
所以必須空一格 或加 "\",如 "發送成功 "或 "發送成功\"
其實這以前在學php課程的時候,老師也有提醒過!

真的是隔行如隔山,不同語言間轉換其實基本邏輯不難
舉例來說,我寫java為主,但是真的要學php的語法應該也不難,反正要什麼功能Google上都可以找到語法或範例
真的難在於 debug的經驗

與其說熟悉一種語言,不如說是熟悉該語言的開發環境及debug經驗
不經一事不長一事啊

2009年9月13日 星期日

MySQL 的調校 (軟硬體、版本、設定)

轉錄自 Gea-Suan Lin's Blog
http://blog.gslin.org/archives/2009/09/13/2088/

把一些關於 MySQL 的資料整理一下。

初期的 MySQL 隨便跑沒關係,備份的部份記得要把 binlog 也一起備份起來,用 gzip 壓過後 (不使用 bzip2 或是高壓縮率參數,是因為考量解壓縮速度;另外推薦用 Parallel gzip 壓縮,速度比較快) 再用 openssl 加密丟到 Amazon S3 上。

成長後,買獨立伺服器要一次買兩台跑 HA,每台分別是:

  • CPU 要考量 SQL query 的方式,如果打算在 MySQL 做很多事情 (i.e. JOIN),CPU 要選高階的;如果大多都是 simple query,則以 C/P 值高的 CPU 優先:兩顆四核心 CPU 算是現在比較划算的硬體。不管哪一種,選低電壓的,像是 Intel Xeon L5408 或是 Intel Xeon L5520,因為硬碟蠻熱的,要減少熱量以免伺服器容易當掉。
  • 記憶體愈多愈好,64GB 算是還蠻基本的。
  • 硬碟選轉速快的 15krpm SAS,挑大一點的硬碟 (以現在的市場就是 300GB) 省得以後空間不夠要搬動。最好是硬體 RAID1+0,依照應用決定單台 database 要多大,如果預定八顆的話可以買 2U 來塞。

軟體的部份:

  • 一定要跑 Linux x86-64 版本,挑大的 distribution 以免遇到問題卻無法解決。我自己還蠻偏好用 Debian。不論是 Debian 還是其他 distribution,儘量跟穩定的 branch,遇到需要升級時的問題會比較少,像是 Debian Lenny
  • 如果要跑 DRBD,先在兩台上面設定好 Heartbeat + DRBD。如果是跑 MMM 的話就設定 MMM,比較需要注意的是 MMM 的版本,參考「MySQL MMM 的情況」。
  • Filesystem 跑 XFS,很多人在上面跑很久了,經過時間考驗的 Filesystem,跑起 MySQL InnoDB 的效率還不錯。
  • MySQL 跑 Percona 的 5.0 標準版本 (非 highperf 版),穩定性還不錯。如果預期到資料量很大的時候會是 I/O bound,可以考慮 Percona 的 5.1 版本,並且開啟 InnoDB Plugin 壓縮的功能。
  • 跑監控程式,把系統的狀態記錄下來。可以是 MuninCacti 或是 nagios,資料對於瓶頸分析很重要。

my.cnf 設定的部份要花不少功夫,除了一般常見的設定外 (這部份網路上很多文件),有些在站台比較大時會發生的問題要注意:

  • back_log 要開大,因為站台大的時候通常不會用 pconnect (每個 web server 都掛著 64 個連線,當有十台 web server 就佔用 640 個連線),而是用 connect,在每次做完事情就斷線,配合 memcached 降低 MySQL 的需求。不過在量夠大的時候,還是會遇到預設的 back_log 不夠。Smugmug 的 CEO 在「Great things afoot in the MySQL community」有提到吃過這個值的虧。
  • max_allowed_packet 設大一點,避免比較大的 INSERT 或是 UPDATE 造成錯誤。通常這是設計上的問題,應該要避免在 MySQL 裡放 blob 資料,不過偶而還是會需要…
  • max_connect_errors 設 4294967295,可以避免當 client (像是 php) 發生太多錯誤時被 block 住。
  • innodb_adaptive_checkpoint 要打開,可以避免在 flush dirty pages 的時候產生 slow query。MySQL 官方的版本沒有這個參數,而這個參數也是為什麼要用 Percona 版本之一。效果可以參考「Adaptive checkpointing」這篇文章。

2009年9月12日 星期六

[教學] 用php發送E-MAIL

用來傳送 e-mail 的描述語言程式(Script)可說是網站上最常見的程式之一。雖然它很單純,但是在某些時候,它卻往往對程式設計師們造成極大的困擾。在 PHP 中有一個函式叫做 mail(),只要有收信者名稱以及訊息內容,就可以拿來傳送訊息。但是你還是需要針對 mail()做某些調整,才能讓mail()為你完成你想做的事。

首先,要讓 mail()能夠運作,你必須先有一個 SMTP 伺服器,好讓你的 PHP 連上去。雖然這個伺服器在電子郵件程式中佔有極其重要的地位,大部分的人還是對它一知半解。在這篇教學指南裡,我們會為你揭開 SMTP 的神秘面紗,並且同時解說關於使用 PHP 傳送電子郵件的某些常見問題。其中精采的內容還包括了:如何以迴圈的程式敘述,讀取電子郵件住址名單,同時針對其中的收件者一一傳送郵件,包括純文字格式以及 HTML 格式的郵件等等。

瞭解你的 SMTP 伺服器
SMTP 是 Simple Mail Transfer Protocol 的縮寫,而 SMTP 伺服器則是透過執行該通訊協定而傳送電子郵件的電腦。基本上,執行通訊協定指的是:如果你使用的是非 Windows 作業平台,執行的是 Sendmail 或 Qmail這類的電子郵件軟體。而如果這部機器使用的是 Windows 作業平台,那麼 SMTP 服務已經包括在 Windows NT Service Pack 中,或者內建在 Windows 2000 裡面,而且,這項服務通常就是正在執行中的電子郵件服務。

這並不是說,SMTP 軟體就只有那幾種,只是它們是最被廣為使用的。如果你的網站是 ISP 的虛擬主機(Vitual hosting)套件的一部分,SMTP 服務應該就已經安裝在主機上面了。如果你是位系統管理者,負責管理某台放在 ISP 或公司機房的專屬主機(Dedicated machine)的話,那麼你很可能會需要在那部機器安裝某種 SMTP daemon,特別用來處理網站伺服器的電子郵件傳遞。

然而,如果你只是一個單獨的使用者,只有一套網站伺服器開發平台在你的個人電腦上面,你可能沒有在你的機器上安裝 SMTP。這裡有個非常簡單但是精確的準則: 如果你是個 Windows 使用者,而你從來未曾聽過 SMTP 伺服器,那麼你就沒有安裝 SMTP。若果真如此,你有兩個選擇:安裝, 設定,並維護一個 SMTP 伺服器(如果你不知道那是什麼,我並不鼓勵你這樣做)或者直接使用已經在你手邊的東西。

「我沒有安裝,怎麼會說在我手邊呢?」你可能會這樣問。嗯,如果你的電腦是透過撥接上網的(或 DSL 或者 cable),你可以直接使用你的 ISP 的外寄郵件伺服器(outgoing mail server)。例如,如果你的開發平台是 Windows 98,以及一台 56Kbps 的數據機,並透過 EarthLink 上網,那麼你可以用 mail.earthlink.net 當作你的 SMTP 伺服器。不管你使用的是哪一種電子郵件客戶端軟體(Eudora,Outlook,Netscape Mail 等等),你的外寄郵件伺服器都可以在 PHP 程式碼中,指定為 SMTP 伺服器。要訣在於,你要告知 PHP 這件事情。

在 PHP 的主要設定檔,php.ini 中,有一些 directive 是你必須去設定,這樣一來 mail() 函式才能夠使用。在更改那些設定以前,你先看看它們是什麼。使用 phpinfo() 函式,可以顯示你的系統目前的設定, 做法是,建一個檔案,包括下列文字:

CODE:
將檔案存起來,放在你的網站伺服器的文件根目錄中。然後用你的瀏覽器去看這個檔案。你應該會看到一個編排良好的現有設定列表。在這裡,你要注意的設定選項為:

SMTP
sendmail_from
sendmail_path
如果你用的不是 Windows,你只須擔心 sendmail_path directive。如果你用的是 Windows,你就要注意先前兩個 directive。

如果你用的是 Linux 或其他 Unix 變種系統,sendmail_path 應該差不多是這樣子設定的:

sendmail_path = /usr/sbin/sendmail

或者,如果你用的是 Qmail:

sendmail_path = /var/qmail/bin/sendmail

在這個 directive 裡面,你也可以設定某些 flag 來指明你的 queuing 做法,或者是用來明確的寫出你的 Return-Path 標題,就像這樣:

sendmail_path = /usr/sbin/sendmail -t -fyou@yourdomain.com

如果你不是 Windows 使用者,你所需要做的就那麼多了。如果你使用的是 Windows,你還有一些事情要處理。你必須看看 SMTP 以及 sendmail_from 的值。不要被 sendmail_from 的 directive 名字中的 sendmail 給搞糊塗了。雖然你在 Windows 上面並沒有用一個叫做 Sendmail 的程式,這個只是 directive 的名字而已。不要緊張。

在phpinfo() 所顯示的結果中,注意一下 SMTP 以及 sendmail_from 原先的設定值 -- 它們應該是空白的,或者只是虛值(dummy)。你必須將它們改為對你系統有意義的值。

如果你真的在你的機器上安裝並啟動 SMTP 伺服器,你的 php.ini 應該要有這樣的設定:

SMTP = localhost

然而,如果你要用你的 ISP 的外寄郵件伺服器(在這裡,我們用 EarthLink 做例子),那麼你的 php.ini 就要有這樣的設定:

SMTP = mail.earthlink.net

你也可以直接用 IP address 而非名字,因為電腦並不會區別這兩者的差異。

第二個我們要設定的 directive 是 sendmail_from,這個是設定在 From 標題(header)裡面所使用的 e-mail 位址。這個設定值可以用 mail 程式更改,但是通常這裡的設定值都被拿來當作內定值。以下是,如果你的電子郵件地址是 youraddress@yourdomain.com, 所應該做的設定值。

sendmail_from = youraddress@yourdomain.com

在更改以上設定值之後,重新啟動你的網站伺服器,再用 phpinfo() 函式來確定這些設定已經被更改了。當你完成這些事情後, 你就已經準備好用 PHP 來傳送 e-mail 了。


傳送一個簡單的 e-mail
mail() 函式相當簡單:只有五個參數,而且其中兩個是選擇性的(optional)。這些參數是:
收件者地址
主旨
訊息
其他郵件標題(選擇性)
其他 SMTP 伺服器的設定選項(選擇性)
額外的郵件標題參數,是用來控制某些電子郵件功能,像是 CC,BCC,Reply-To fields,或其他 SMTP 通訊協定所規定的功能。 在這個例子裡,我只用 From 以及 Reply-To 電子郵件標題。

如果你要送 mail 給我,而你用的不是 Windows 系統,那麼它看起來會像這樣:

CODE:
如果你用的是 Windows 的 SMTP 服務,那麼很可能你不需要設定第五個參數,以及額外的郵件標題參數 (即第四個參數),不過你要用 \r\n 而非 \n 將你的參數分開。因此,同樣的電子郵件,透過 Windows 的 SMTP 服務傳送,看起來會是這樣:

CODE:
在以上程式中的 echo 敘述,是讓你的網頁瀏覽器在執行完這個程式後,回傳給你一個訊息。如果沒有這項敘述,你會收到一個「Document contains no data」對話方塊,因為沒有東西傳送到你的網頁瀏覽器上。

mail() 函式只要連到指定的 SMTP 伺服器,就會回傳 true。這並不意味著郵件已經成功抵達收件者了。mail() 函式並不會等 SMTP 伺服器告訴它傳送成功或失敗。

mail() 函式會回傳 false,並且送給你一個警告,像是「Couldn't connect in line x」 或者是「Unknown error in line x」。如果你沒看到前面兩個訊息,檢查一下 php.ini 的 SMTP 設定值。有兩種可能性會導致這個訊息的產生:SMTP 伺服器當掉了,或者是 PHP 沒連到 SMTP 伺服器。當然,這兩種情況下, 你的電子郵件都不會被傳送出去。

這個程式用的參數都是寫死在程式中的。你可以透過一個簡單的 HTML 表格,將這些值送出去,然後再回傳給你一個回饋表格(feedback form)。

以迴圈讀取傳送名單
一旦你知道要怎樣傳送電子郵件給一個人,你或許會感到非常興奮而且想傳送同樣的訊息給很多收件者 --就像電子報一樣。你只要做一個簡單的迴圈敘述, 一一閱讀你名單上的名字,然後傳送電子郵件給他們。

mail 函式的格式是一樣的:

mail([recipient], [subject], [message], [any headers]);

你必須將 [recipient] 換成迴圈中你的名單的下一個名字。假設你有一個 e-mail 地址的陣列:

$addresses = array("me@mycompany.com", "you@yourcompany.com", "someone@otherplace.com");

你只要以迴圈讀取這個 array, 取得新的電子郵件地址,然後傳送郵件。

如果你的電子郵件地址名單是存在資料庫裡面,你還是可以用同樣的方式:以迴圈一一讀取它們。

就是這麼簡單。顯然的,同樣的觀念可以運用到你特定的資料庫種類以及表格(table)架構, 雖然程式碼必須做一點修改。

這裡還有一個小小的訣竅,在以迴圈敘述讀取一串電子郵件名單的時候,似乎每一個人都忽略了它:如果你有多於五十個郵件地址,你的程式或許在還沒完成讀取名單的時候,就逾時(time out)了,因為 PHP 對每個程式的內建時間限制是三十秒。你可以修改這個時間限制, 但是要小心。試著將這個修改的效果限制在某些特定的程式中, 例如迴圈讀取電子郵件名單並且傳送郵件。否則的話,你可能會有一些伺服器程序 (server process) 一直在你的伺服器上,你的主機會幾乎停滯,整個世界就會停止。

要在程式裡面設定時間限制,使用 set_time_limit() 函式。你可以指定這個限制,例如六十秒(set_time_limit(60)),或者你可以讓它一直等下去,(set_time_limit(0))。

將這個放在你的程式中,你傳送電子郵件的迴圈敘述就會一直持續下去直到名單中所有的地址都傳送出去為止。

傳遞 HTML 格式的電子郵件
傳送 HTML 格式的 e-mail 是另一個看起來困難但是做起來簡單的事情。一旦你知道怎麼做,你或許會為了以前把它想得太困難而想打你自己一頓!

我們需要對先前用過的基本電子郵件敘述程式做兩個修改:

你的郵件訊息應該是 HTML 格式的。
你必須增加內容種類郵件標題(content-type header)。
這樣就可以了。使用者如果擁有可以讀取 HTML 格式郵件的電子郵件客戶端軟體的話,他所看到的郵件訊息會是大型的粗體字形。如果你傳送的 HTML 格式的電子郵件有影像的 tag 在裡面,你必須記得在 src 屬性中使用完整的 URL。例如:

記得,不是所有人都可以讀取 HTML 格式的電子郵件,如果使用的軟體不能讀取 HTML 格式的電子郵件,那麼收件者就只能看到 HTML 程式碼。這會讓人有點受不了,所以小心使用這項功能。

結論
你可以用幾乎你所能想像得到的所有各種不同的方式,使用 PHP 傳送電子郵件。這篇文章只有接觸到基本面而已:設定你的伺服器,並且傳送一些簡單的電子郵件。你也可以用 mail() 產生的電子郵件來傳送附件,修改很多不同的郵件標題。大致上說來,你也可以用 PHP 做任何現實生活中, 電子郵件客戶端軟體或郵件名單程式可以做到的事情。

2009年9月9日 星期三

ECFA即將簽署,台灣網路界可以要什麼?

ECFA說白話,就是台灣與中國的共同市場,也就是最惠國待遇的最極致
商周最近報導了一篇 ECFA對於台灣的影響
http://www1.businessweekly.com.tw/web/webarticle_37802_p1.php
裡面提到,ECFA是ECFA是富人的威而剛、窮人的土石流,
按WTO架構,ECFA屬過渡協定,雖無強制性,但通常在10年內,兩邊必須完成約90%的商品服務免關稅,台灣與中國將互相大幅開放市場給對方。

所以兩國間強者將恆強,台灣的優勢項目可以在大陸賣得更好,大陸的優勢項目可以在台灣賣得更好,也勢必帶來產業的重整。

在其他產業紛紛向政府施壓,希望將產業的需求列入ECFA談判
台灣網路界能不能也站出來大聲說出自己的需求
為何台灣的網站要到大陸,要申請ICP執照,要符合當地人成立資本額100萬人民幣的標準,
而大陸網站來台就沒有任何限制?

目前申请ICP许可证的条件?
1 经营者为依法设立的中资公司
2 注册资金达100万及以上
3 有为用户提供长期服务的信誉或能力
4 有业务发展计划及相关技术方案
5 有健全的网络与信息安全保障措施
6 国家规定的其他条件

台灣網路界能不能集結向政府呼籲,在ECFA中一併談判將中國所設立的壁壘消除?
中國希望管制言論,可以比照當地的標準審核。
要申請ICP,也可以比較當地去申請。
資本額100萬人民幣,也不是難事。
但是「限中資公司申請」,就很不合理
台灣或外商必須透過人頭成立中資公司,徒增困擾及可能的糾紛
既然要共同市場,就應該一併把這個限制消除
讓台灣網站有機會直接與對岸網站一較高下

有沒有人願意一起來連署呢?