顯示具有 php 標籤的文章。 顯示所有文章
顯示具有 php 標籤的文章。 顯示所有文章

2009年5月19日 星期二

digitalus

http://digitaluscms.com/

這個專案是以Zend Framework及jQuery做為基礎構建的cms管理系統,整個系統的程式碼有一種熟悉的感覺,因為Zend Framework及jQuery正好是我最熟悉的兩套開發框架,Zend Framework是Zend官方團隊所維護及發展的,最能展現PHP物件導向的威力,jQuery是最受歡迎的javascript開發框架,兩者的結合正好可以當做我研究的對象。

架好後,整套系統運作很順暢,只是專案的討論區上人氣稀疏,套件中有的功能並沒有全部實做,上open source的cms網站上看,這個專案並沒有被列為cms的選擇之一,想想也對,雖然專案有Zend Framework及jQuery的加持,但功能並不完整,最嚴重的缺點,就是套件必須安裝在apache上的根目錄上,這是在開什麼玩笑,難不成為了安裝這個套件,得弄一個虛擬主機,如果以子目錄安裝,圖片都不會出現,有的功能也不能使用,這應該是路徑的問題,其實不難解決,更動的程式碼應該不會太多。

整個套件的發展潛力十足,很容易安裝,大概十分鐘就裝好了,邊看網站上的tutorial,邊操作,只須二三個小時就能上手了,功能不複雜,非常簡單易用,套件以mysql為資料庫,資料庫引擎使用innodb,這點我非常欣賞,一堆的cms都是使用MyISAM資料庫引擎,這真的不是一個好的選擇。

digitalus雖然潛力十足,但前途未明,不知道未來走向如何,拿來研究,改進自己的程式碼應該不錯,但是如果套用在上線的程式上,就太可怕了,整個套件的用法應該會再變動,程式寫法也還會做變化,先看看再說,免得被當做試驗品。

2009年5月17日 星期日

PHP is NOW

PHP is NOW


資料來源:

http://www.ibuildings.com/blog/archives/1554-PHP-is-NOW.html


原始作者:

Cal Evans
Director of PCE
Cal Evans
是Ibuildings公司的PHP專業發展中心的主管,他已經在IT產業26年了,過去9年,專注於PHP及MySQL領域。 Cal 是PHP書籍及文章的作者,並且在世界上許多的PHP會議場合演講, Cal 的部落格在 http://blog.calevans.com


翻譯:

羅仁治


php正在轉折點上,目前有許多的因素促使php的應用加廣加深,並把scripting language的標籤撕掉,成為企業開發時的正式工具。


許多php社群的開發者在過去幾年已經將php視為正式的開發工具,Digg, Expedia, Yahoo 及 facebook這些公司在php的討論會議上一再證實php是一項有用的工具,另一些公司,Ladbrokes, Channel Five, Fiat, Panasonic, 以及 BBC,他們不但使用php做為系統背後的整合性程式語言,也將他應用在正式地,企業等級地交易流程系統中。在數目不斷成長地大型開發商中,php己經從為何使用的思考邏輯變成了為何不使用的問題。


開放源碼的經濟效益

許多因素的匯聚造成了這個轉折點,目前的世界經濟局勢是最大的影響因素,在泡沫經濟期間,公司很容易花費六位數或七位數的代價購買私有軟體,這可看出IT系統缺乏投資報酬率,經濟狀況好的時候,經理人依據老闆專業術語數量的平方做為採購依據,換一個有趣的方式說明,就是在經濟狀況好時,IT系統能不能跟上潮流是判斷的依據,而不是根據最低的貢獻度。


當狀況轉壞時,IT預算緊縮,新科技必須展現在公司財務報表中的貢獻度,而不是順應潮流。


在軟體經濟時代,開放原始碼及php與私有軟體相較,有許多優勢,當然,php最大的優勢就是不須授權費用,php php的延伸功能 PEAR PECL 以及以php搭建的開發框架都是免費的,暨然不用授權費,維護費及購買費用,以更少的IT預算就可以做更多事情。


即使經濟情勢呈現下滑的走勢,免費仍然不是佈署php的決定性理由,PHP有自己的方式增加附加價值,從簡單的類別庫到系統的佈署都有公司提供支援或服務,許多公司,像Zend, php|architect, NuSphere 會替別的公司或開發人員,開發須支付費用的開發工具或服務,這樣的方式,與開放原始碼公司 EllisLab, Sensio Labs 及 Acquia 的營運方式雷同,PHP免費,不代表跟PHP相關的所有東西都是免費的,當與PHP相關的產品或服務不是免費時,公司必須決定他們的標價是不是增加了公司的價值。


這個工具變得更強大了


第二個因素是即將釋出的php 5.3版本,PHP 5.3目前在RC階段,最終版本會在2009年夏天公佈,PHP 5.3不像大部份的小改版,他是有許多新功能的大改版,PHP物件模型的改變,強化的新語法,引擎的改善,使他比之前的版本快速穩定,PHP的核心開發成員花了很多時間強化穩定度,並加強PHP引擎—Zend Engine的功能,雖然每一個新的PHP版本會帶來一些新功能,只有PHP 5.3提供有價值的強化功能。


php有許多朋友


我們提到了PHP系統,也提到了供應者的深度及廣度,然而,造成這個轉折點的另一個因素,是PHP現在開始被許多大廠支援,他們對php的成功有商業興趣,IBM釋出了WebSphere sMash (也就是大家熟知的 ProjectZero)。sMash上的php是在JVM上執行的,而不是在Zend Engine上跑,sMash上的php並沒有包含所有的php延伸套件,但己經可以執行許多的重要應用,像是SugarCRM 及 phpBB. IBM採用ProjectZero,代表對php語言的承諾及擔保,他們選擇php做為開發的語言不只代表他們對這個語言的強大信心,也對圍繞在php四周的社群投下信任票。


微軟對php的興趣每年都在增加,開始時是在2006年,對事業伙伴Zend感興趣,再來是每年發表的Microsoft Web Developers Summit都會有PHP,他們已經承諾,會讓PHP在windows上長期地健康發展,他們甚至雇用了一位全職的php核心開發人員,強化windows上的PHP,努力的成果,就是最近在FastCGI上發表的PHP,PHP在windows上的成熟度就跟.net或java相同,可以用來開發各種規模的web應用程式。


Oracle長期支援PHP,了解並支援社群,鼓勵他們使用公司的旗艦產品,Oracle會透過Christopher Jones定期釋出PHP核心的函式庫或程式碼,此外,他們也會對PHP的會議提供財務或其他援助,像是即將到來的Dutch PHP Conference.就接受Oracle的援助。


最後一位但不是最不重要的一位朋友,是 Adobe 。他們援助的計畫,像是 AMFPHP 及 Zend_AMF, 將PHP整合為Adobe開發工具的一部份。


結論


這三個因素相加,經濟情勢轉壞,下一個版本的強化,及大廠的支援,共同指出2009第二季到2010,PHP在企業開發領域占有一席之地,PHP非常普及,穩定並有良好支援,如果你問到IT經理人,採用新科技的三個因素是什麼,他們會至少說出其中的二個原因,這是PHP的轉折點,對開發人員而言,這代表更多的機會,對IT經理人來說,這開啟了許多不可能實行的專案另一道門,不論如何,PHP時代的到來,意味著人人有機會成功並互相分享。


Ibuildings是PHP的支援廠商,我們相信,回饋社群是我們的義務,他們給了我們機會站在領先地位,我們也是世界上PHP開發商的翹楚之一,不論你是才剛開始探索PHP的可能性,或是找尋一位伙伴實現這些可能性,我們希望可以和你一起奮鬥,就像是許多公司一樣。


(c) 2009 Ibuildings All rights reserved. Use by permission

2009年2月9日 星期一

php編輯器比較

目前我正在使用的php編輯器有兩套,一套是eclipse pdt,另一套是netbeans ide,這二套編輯器都是開放源碼軟體,不用付費就可以使用。eclipse pdt可以在www.zend.com的網站上下載使用,netbeans ide可以在www.netbeans.org網站上下載。

這兩套軟體的操作概念都非常類似,所有相關的程式碼、檔案、圖片等等資源匯聚成一個專案,再針對專案撰寫程式,或進行設定。在進行程式碼撰寫前,必須先建立一個專案,專案其實就是一個目錄,將所有的程式碼、檔案等等資料放在這個專案裡(目錄),以便進行專案的設定或管理。

eclipse除了專案的概念外,他與netbeans還有一個不同點,eclipse有workspace的觀念,workspace其實也是一個目錄,所有的專案都必須放在這個workspace下,不然eclipse就會找不到相關的專案,如果放專案的位置與目前的workspace不同,就必須切換workspace的位置,才能使用專案。netbeans就沒有workspace的觀念,設定專案時,就必須指定專案的目錄位置,專案可以散落在各個不同的目錄。

eclipse的檔案管理能力比較強悍,程式碼自動補齊的功能也比較完善,在eclipse中,可以直接匯入或匯出檔案,但在netbeans中就沒有這個功能,必須用檔案總管進行拷貝的動作,如果在eclipse中直接拷貝檔案是會出問題的,一定要用內建的檔案匯入匯出功能,eclipse會追蹤這些檔案訊息,如果直接拷貝,eclipse就無法追蹤了。

eclipse的畫面比起netbeans,真是漂亮太多了,我不太喜歡使用netbeans,畫面感覺比較粗糙,沒那麼有質感,這二套軟體的鍵盤快速鍵,不太相同,轉換編輯器時會有一段適應期。

eclipse的php檔案內如果含有html碼,如view檔案,這類php檔就會有排版用的html碼,eclipse的自動重排功能沒有辦法把html排得很整齊,他會把html和php程式碼混在一起,不重排還好,一重排簡直慘不忍睹,netbeans這方面的功能就好太多了。

這二套編輯器都要花一段時間適應,操作上各有千秋,不過我比較喜歡使用eclipse,eclipse有免安裝的版本,下載後直接解壓縮後就能用了,netbeans就一定要安裝,不過安裝的速度很快,一直按下一步就好了,這二套軟體都是跨平台的,目前我家裡的作業系統是ubuntu,上班的地方是xp,這樣就不會有跨平台的問題了,這大概就是開放源碼的好處吧!轉移作業系統比較方便。

2008年10月8日 星期三

連接mssql

http://www.zxbc.cn/html/20070506/13033.html

2008年8月31日 星期日

php無法執行

最近這幾天,在apache上都沒辦法跑php,我本以為是改了哪邊的設定檔,才造成只要一執行php檔,就造成php檔被下載,而不是被執行的狀況。

設定檔找了老半天,都找不到錯誤,不過把apache的php_gtk2的功能拿掉,立刻就正常了,真是見鬼了,前一陣子在玩php-gtk,只是弄個測試程式玩玩,沒想到會造成php在apache的環境下無法執行,不過也多了一次經驗。也不錯啦。

強化上傳目錄的安全性

如果在網頁程式中實做上傳檔案的功能,為了強化程式的安全性,會針對檔案的附檔名做過濾,並且限制上傳的目錄位置。這樣做的目的,只有一個,確保使用者不會亂來,在server上動手腳。

除了在程式中,使用程式碼確保server的安全外,還可以在apache中設定,再加上一道防護措施,
就是在上傳目錄中,新增.htaccess檔,這個檔案中再加上下面這道命令

php_flag engine off

那麼這個目錄下的php檔案都不會被apache解譯及執行。

要這麼做,你的apache的override必須設成All。

2008年7月31日 星期四

shaker排序法--單邊

只有單邊的shaker排序法,應該比雙邊的shaker排序法慢

$length=rand(8,10);

for($i=0;$i<$length;$i++)
$a[]=rand(200,300);

$left=0;
$right=$length-1;

while($left<$right){
$shift=0;
for($i=$left;$i<$right;$i++){
if($a[$i]>$a[$i+1]){
$tmp=$a[$i];
$a[$i]=$a[$i+1];
$a[$i+1]=$tmp;
$shift=$i;
}
}
$right=$shift;
}


foreach($a as $num)
echo $num."\n";
}

2008年7月23日 星期三

memcached的使用

http://dev.mysql.com/doc/refman/5.0/en/index.html
http://tw2.php.net/manual/en/book.memcache.php

Memcached

introduction
在一般的IT環境下,如果要擴增程式的使用人數,最大的問題會卡在程式的執行速度,經常存取的資訊,如果使用mysql做為後端存取的資料庫,速度就會變得慢,因為資訊的存取,必須透過執行sql語法,取得資料庫內相關的資料,而拖慢執行速度。

memcached是一個簡單的、具有高度伸縮性的key-based快取,快取來源不受限制,他也是一個備份的RAM,可以讓應用程式進行非常快速地存取,要使用memcached,必須在一台或多台主機上執行memcached,讓使用者共享快取內儲存的物件,因為每台主機都是使用RAM儲存資訊,存取的速度遠遠快過從硬碟上進行資訊的存取,這樣的話,相對於從資料庫存取資料,效能的增進是非常明顯的。快取只是容納資訊的空間,你可以在快取內儲存任何資料,如果儲存的是複雜的資料結構,可以在資料存進快取前,先進行複雜的資料庫操作,再將資料放進快取中,可以大幅減少mysql server的負擔。

使用memcached的一般性作法是修改應用程式,讓應用程式改為從memcached讀取資料,如果需要的資訊不在memcached裡頭,程式就改由mysql讀取資料,再將資料寫入memcached裡頭,以後如果要存取相同資料,就可以發揮memcached資料快速存取的優勢。

在memcached的架構中,所有的client可以送出key與任何一台memcached伺服器連繫,在這個架構中,每個client可以與圖中的任何伺服器連繫,在client上,當送出要求時,key會先被hash,這個hash值會被用來選取memcached伺服器,memcached伺服器由client決定,可以使程式維持輕量化。

當client送出key時,會執行同一套演算法,相同的key,會產生相同的hash值,同一部memcached伺服器就會被選為資料來源,使用這個方法,快取資料被分散放置在所有的memcached伺服器上,而這些快取資訊可以被所有的client存取,結果就是,以記憶體做為資料儲存處的分散式快取,這類型的快取尤其適合複雜的資料結構,存取速度遠遠快過直接從資料庫存取資料。

在memcached伺服器中的資料永遠不會放在磁碟上,記憶體中的快取可以從後端的資料庫(mysql)取得資料,如果memcached伺服器當掉了,可以改為由mysql取得資料,當然,速度會變得比較慢。


Installing memcached

在ubuntu上安裝memcached非常輕鬆,只要輸入下面這道指令,再按enter就安裝好了

apt-get install memcached

memcached的啟動

在ubuntu上啟動memcached伺服器

/etc/init.d/memcached start

參數配置

參考/etc/memcached.conf設定檔的說明會更清楚

-u 執行身份
-m 記憶體容量(快取容量,單位為MB)
-p 指定port
-d 以daemon方式執行
-t 指定執行緒的數量
-l 指定執行的網路介面


memcached deployment

memcached有許多不同的佈署方式及策略,正確的佈署方式取決於你的應用程式及環境,當在系統中佈署memcached,你必須考量下列的注意事項

*memcached只是一項快取機制,如果資料很重要,在存取的過程中不能因為漏失,再從不同的地方存取,就不能使用memcached。

*memcached沒有內建的安全機制,至少,你必須確定,memcached伺服器只能在內部網路存取,而且memcached伺服器使用的port不能被外部網路存取。如果memcached含有敏感性資料,這些資料在存進memcached前要先被加密。

*memcached不提供復原機制,因為memcached之間沒有任何的溝通協定,如果一台memcached故障了,你必須將這台memcached從列表中移除,再重新載入資料,再將資料寫入另一台memcached伺服器中,

*如果client及memcached分別在不同的機器上,資料傳送延遲性如果造成問題,可以把memcached服務移到client端的機器上。

*key的長度是由memcached伺服器決定,預設的最大長度是250byte

*只使用一台memcached絕不是一個好的想法,尤其是服務多個client時,最少提供二台
memcached,才可以恰當地管理機器當機的狀況,如果可以的話,應該多建置幾台memcached
伺服器。當增加或移除memcached伺服器時,key/value的配置及hash值就會受到影響,如果要避免這些問題,必須研究memcached的hash type。


Memory allocation within memcached

當你第一次啟動memcached伺服器,memcached參數指定的記憶體數量不會自動配置給memcached,相反地,當開始將資料存進memcached的快取時,才會進行記憶體的分配。

當你開始將資料存在快取中,memcached不會為每個存入快取的資料一一配置記憶體空間,而是一次配置一個區塊,以進行記憶體空間的有效利用,避免快取資料過期時,造成記憶體空間配置的零碎化。

memcached裡頭的快取記憶體配置,以page為單位,每一page預設是1M,一個或多個page組成一個slab。

當memcached啟動時,不會進行slab及page的配置,只有當資料存進快取時,才會在page中切出適當大小的chunk,把資料存進chunk中,每一個chunk,會儲存一筆資料的value跟key,而page中每筆chunk的大小都必須一樣。

例如,memcached啟動時,有一筆資料的大小是800k,須要存入快取,這時就會建立一個slab,這個slab中page的chunk大小就是1M,一個page就只有一個chunk。

如果存入快取的資料是250K,那麼,就會建立一個slab,這個slab會再建立一個page,這個page會再切成4個大小相同的chunk。如果還有6筆250K的資料要存入快取,這個slab會再建立第二個相同的page進行資料的儲存。

資料如果超過1M,由於chunk預設是不能超過一M,而且資料必須塞進chunk中,因此超過一M的資料就會無法存入快取當中。


Using namespaces

memcached是非常簡單的key/value型式的儲存系統,無法自動將資料進行分類,例如,如果你使用mysql資料表傳回的id當做存入memcached快取的key時,就有可能有二筆由mysql資料表傳回的資料,雖然內容不同,id卻相同,存入快取時這二筆資料就會相互覆蓋,造成資料讀取的錯誤。

一些程式的API會在資料存入快取時,自動建立命名空間,實務上,這些命名空間,只是在存取資料時,在key前加上區別的字串。

你可以自己實做命名空間,只要存取快取資料時,在key前加上自定的字串就可以了,如加上”user_”字串。


Data Expiry

memcached快取資料的過期有二種狀況,如果要插入新的資料到快取中,但是沒有適當地slab可以存資料時,最近最少使用的資料會被移除,以騰出空間讓新的資料存入。

這個方法可以確保被移除的資料,是不再被使用的,或是已經很久不被使用的,但如果memcached的快取容量,比正常狀況使用時小很多時,你就會看到很多尚在使用的資料被移除了。

啟動memcached時啟用 -M參數,會在記憶體不足時發出警告,而不是自動刪除舊有的資料。

第二種快取過期的狀況,是直接刪除快取資料,或是設定資料過期的時間。

一種典型的應用就是設定使用者儲存的session資料,快取過期的時間。


在php中使用memcached

api的安裝

apt-get install php5-memcache


程式範例

程式名稱:a.php
class Test{
public $model;
public $color;
}

$test=new Test();
$test->model='bmw';
$test->color='red';

$cache=new Memcache();
$cache->connect('localhost',11211);
$cache->set('car',$test);


程式名稱:b.php
class Test{
public $model;
public $color;
}

connect('localhost',11211);
$car=$cache->get('car');

echo $car->model;
echo “\n”;
echo $car->color;
echo “\n”;

跑完a.php程式後,再跑b.php,就會跑出下面的結果
bmw
red

程式中物件的二個屬性都是經由serialize後,由a.php存在快取中,如果其他的程式要取用這二個屬性,只要有快取的key值,就可以得到這個物件的屬性。

2008年6月24日 星期二

上傳檔案的設定

http://www.php.net/manual/en/features.file-upload.common-pitfalls.php

php相關設定
upload_max_filesize
memory_limit
max_execution_time
post_max_size

mysql相關設定
max_allowed_packet

撰寫上傳物件的問題

想要寫一個檔案上傳的物件,以方便以後程式碼的重複使用,不必重造輪子,做相同的事情,仔細思考很久,如果上傳的檔案都存在目錄裡,還必須考量到檔案備份、程式碼中檔案上傳的安全性,使用者上傳的檔案名稱也必須做管控,才能避免檔案重複,造成檔案彼此覆蓋的問題,因此決定將上傳物件,寫成將插入資料庫的型式,如果以物件導向的模式方式思考,其實應該實做一個interface或abstract,再分別撰寫要上傳至資料庫的物件,及上傳至目錄的物件,這樣才能顧及程式的擴展性及可維護性,不過現在沒想那麼多,先能用就好了。

檔案存到資料庫中,只要必份資料庫並小心權限設定,程式碼使用prepared statement操控資料庫,就可以避掉sql injection及檔案備份的問題,以後只要備份資料庫就可以了,而不用再備份檔案,也不用再花心思控管上傳檔案的安全性。比較省事。

上傳物件,在網路上有許多現成的程式碼可以參考,各種寫法看了讓人頭昏眼花,參考了php manual後,最後決定使用file_get_contents函數進行檔案的處理,這個函數是php manual上建議使用的函數,雖然php 6.0以後才會完整支援所有的參數,但轉換檔案為string時,這個函數的轉換效率是最好的。

如果使用fopen開啟檔案,再使用read()函數進行讀取,要記得加上參數'rb',如fopen(檔案,'rb'),因為windows系統對待binary跟文字檔是不同的,所以要記得加b,操作時才不會出錯。

測試上傳物件時,檔案比較大的物件上傳時,都會被切成只有64k,找程式碼找了半天,也找不到錯誤,後來,在mysql manual上找到原因了,blob的儲存上限是64k,mediumblob是16M,bigblob是4g,改欄位的資料型態就一切正常了。

另一個在測試時碰到的問題,就是中文檔名下載時會出會錯誤,只要使用urlencode()函數將檔名重新編碼,就不會有這個問題了。

2008年6月11日 星期三

php上傳物件

參考網址

http://www.devshed.com/c/a/PHP/Developing-a-Modular-Class-For-a-PHP-File-Uploader/1/


檔案上傳物件

上列網址是一個檔案上傳物件的實例,用了一些php內建的函數及物件,使用內建函數及物件,執行效率會提高(因為是用c寫的),程式內也用了迴圈的方式把全域陣列$_FILE中的key/value都對應到物件中的屬性,這樣就不用寫一堆討人厭的$_FILE['userfile']['name']這類一長串不好輸入的字元,整個程式碼很清爽。

撰寫這個物件的背景知識

使用的函數及物件
Exception物件
in_array()函數
move_uploaded_file()函數

使用的全域陣列
$_FILE['userfile']['name'] 原始檔名
$_FILE['userfile']['tmp_name'] 儲在server上的暫存檔名
$_FILE['userfile']['type'] 檔案的mime型態
$_FILE['userfile']['size'] 檔案大小,單位是byte
$_FILE['userfile']['error'] 上傳錯誤,錯誤代碼查php manual就知道了


從上列網址post上來的上傳物件的範例程式碼


class FileUploader{

private $uploadFile;

private $name;

private $tmp_name;

private $type;

private $size;

private $error;

private $allowedTypes=array
('image/jpeg','image/gif','image/png','text/plain','application/ms-word');

public function __construct($uploadDir='C:uploaded_files'){

if(!is_dir($uploadDir)){

throw new Exception('Invalid upload directory.');

}

if(!count($_FILES)){

throw new Exception('Invalid number of file upload parameters.');

}

foreach($_FILES['userfile'] as $key=>$value){

$this->{$key}=$value;

}

if(!in_array($this->type,$this->allowedTypes)){

throw new Exception('Invalid MIME type of target file.');

}

$this->uploadFile=$uploadDir.basename($this->name);

}

// upload target file to specified location

public function upload(){

if(move_uploaded_file($this->tmp_name,$this->uploadFile)){

return true;

}

// throw exception according to error number

switch($this->error){

case 1:

throw new Exception('Target file exceeds maximum allowed size.');

break;

case 2:

throw new Exception('Target file exceeds the MAX_FILE_SIZE value specified on the upload form.');

break;

case 3:

throw new Exception('Target file was not uploaded completely.');

break;

case 4:

throw new Exception('No target file was uploaded.');

break;

case 6:

throw new Exception('Missing a temporary folder.');

break;

case 7:

throw new Exception('Failed to write target file to disk.');

break;

case 8:

throw new Exception('File upload stopped by extension.');

break;

}

}

}

?>



物件使用範例




try{

if($_POST['send']){

require_once 'fileuploader.php';

$fileUploader=new FileUploader();

if($fileUploader->upload()){

echo 'Target file uploaded successfully!';

}

}

}




catch(Exception $e){

echo $e->getMessage();

exit();

}

?>