最近更新: 2007-06-25

為什麼還不升級PHP5

jaceju 於《PHP5 將滿 4 歲》一文中說了一些他碰到的原因。

我的經驗,應用軟體的問題還好,大部份 PHP4 的軟體在 PHP5 的環境上一樣可以跑,只是語法 notice 多了點。再者,在 PHP4 的軟體中混雜 PHP5 的語法也不會影嚮程式運作。

我做過一件在 Xoops 下開發新模組的案子,執行環境是PHP5。因為我的開發環境設置 error_reporting = ALL ,所以看得到 Xoops 跑出不少語法的 notice 。但一般環境只設置 error_reporting = ERROR ,所以不會看到 notice 等級的訊息。儘管有許多語法 notice , Xoops 還是可以在 PHP5 運作。而我依然可以用 PHP5 的語法寫新的 Xoops 模組。

但虛擬主機商是一個很大的障礙。只要它們不升級到 PHP5 ,我們就只能跑純 PHP4 的軟體,不能跑混雜 PHP5 程式碼的軟體。

目前我在寫的 PHP 程式,幾乎都限 PHP5 (version 5.1.x) 。有兩點原因:

  1. 我很難割捨 PHP5 增加的 magic methods。少寫一堆重覆的 method code。使用上彈性更大。
  2. 很多 extensions 也是 PHP5 才有或者內建。像 PDO、SimpleXML、DOM、XSL等。 JSON、Zip 在 PHP 5.2 以後成為內建extensions。

台灣並不是沒有 PHP5 的好書,我之前就介紹過一本。儘管那些書都是外文翻譯,但內容大多是有口皆碑。台灣的 PHP 使用者並不是沒有書可以看。然而正如 jaceju 所言,眼下多數 PHP 使用者並不想深入了解 PHP 。他們只停留在初級階級:用直敘的程式碼解決特定問題。按我在 TWPUG、藍色小舖等站看到的問題內容,會令我懷疑那些人還在看 PHP3 的書。

每種程式語言的使用族群中,都有這一類程序員存在。但 PHP 的易學與普及性,使許多這一類程序員轉移到 PHP 領域。他們寫出了許多結構不好的程式碼,令 PHP 蒙受不白之冤,被人說程式碼結構不好。這真是外行人的說法。程式碼結構好或不好,跟程式語言沒有關係,而是看程序員如何設計。難道 Java 就沒有結構不好、各種目的混在一起的程式嗎?我照樣見過不少。《Java AntiPattern:避開Java開發的失敗經驗》中還有專章說明「神奇按鈕」。在 JSP framework 出現前,Java 程序員寫 servlet 時犯的毛病,與 PHP 程序員差不多。

說來說去,人的思想精神才是關鍵。只要有心,人人都可以是食神... 呃,更正。人人都可以是 PHP5 高手。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/3526951.html

樂多舊回應
未留名 (#comment-11043179)
Mon, 25 Jun 2007 22:27:55 +0800
「真‧PHP 5技術手札」我也買了,但它依舊不是台灣人自己寫的...orz (不過的確是不錯的參考書籍) 。

市面上可以看到台灣作者寫的 PHP5 書籍,但是大部份都只是在介紹 PHP5 的語法;要看到真正有討論到進階的技巧 (我指的不只是 extension 而已) ,還是得依賴國外的資訊。

而且台灣開發人員有種很奇怪的習性,就是用了哪本書入門,那麼這本書的用法幾乎就會影響他往後的開發方式,即便這本書有些地方的資訊是並不是那麼正確 (或過時了) 。這樣一來,就算 PHP5 有再強大的特性,對他們來說似乎也沒什麼用途。

所以如果不能多多充實自己對語言的瞭解,那麼就算是使用 RoR 或是更強大的語言也是枉然。我非常同意石頭成老大後面所說的,我更認為精進自己的思想觀念才是學習程式開發最佳的途徑。
racklin@gmail.com(racklin) (#comment-11045809)
Tue, 26 Jun 2007 09:21:18 +0800
個人覺得 PHP5(Zend Engine 2) 最大的演進, 在於 Exceptions / SPL / OO 的導入.
這讓 PHP5 由 Scripting Language, 成為一個更為強固的語言.
利用 Exception , 我們不再是利用 @function_name 或 set error_reporting 的方式來 "隱藏" 或 "吃掉" 問題, 而是主動把可能發生例外的地方 try catch 起來, 這讓用 php5 開發的 web site 更加強固及可預測性.
而 SPL 則提供了 collections 及 interator interface, 這個在 java 中是大量被使用的方法.
結論: PHP5 擁有了類似 java 的特性, 卻保有了 PHP 的精巧及簡便.
未留名 (#comment-11047773)
Tue, 26 Jun 2007 12:15:28 +0800
SPL 啊,真不知該說它好還是不好。文件語焉不詳,使用方式又很不直覺,效能也不如傳統方式。八成就是因為它在這方面學得是 Java 而不是 C++ 。

像 Ruby 那樣的實現方式多好。
HACGIS@gmail.com(tokimeki) (#comment-11053485)
Tue, 26 Jun 2007 22:28:39 +0800
其實這問題還可以延伸到我對FreeBSD打補釘的感想。

最近半年PHP的一些修正放得很頻繁,可是我並不是每次都會去重新編譯,因為我知道,最保險的方式是build world。

我一直在想,有沒有一個「公板」的環境,或是一個套件能解決打補釘的問題?

前一陣子好像有看到,不過還沒試就是了~
未留名 (#comment-11054719)
Wed, 27 Jun 2007 00:15:55 +0800
SPL 真的怪 php 官方文件不清不楚.
其實 SPL focus 在標準介面上,而不是效能上面, 這個同 Java 中的 primitive array 和 Collections Framework 的應用時機相同的, primitive array 一定比 collections 快, 但是不同的時機有不同的考量..
而 iterator 在 php 上, 己經相當"神奇"且直覺的嘍..
另開專文一起討論嘍.

http://racklin.blogspot.com/2007/06/iterators-in-php5.html
未留名 (#comment-11064447)
Wed, 27 Jun 2007 18:02:51 +0800
哈哈,你說"神奇",那就或多或少表示它不直覺。

舉例來說,ArrayAccess 中有4個方法, offsetGet, offsetSet, offsetExists, offsetUnset 。其中 offsetGet, offsetSet 按 C++ 觀點,其實就是 [] 運算子方法。 C++ 就直接寫成 operator[] 。 Ruby 寫成 [] 和 []= 。這一看就知道當我定義這方法後,便可像 primitive array 一樣用 [] 運算子存取內容。

我在 Google 上找到一個 ArrayAccess 的使用例子,結果作者全都寫成方法調用的形式 ($a->offsetGet(),...),而不是用 [] 運算子。似乎作者不知道可以這樣做, SPL 的優點完全沒有展現出來。

再說到 offsetExists, offsetUnset 。剛好在 magic methods 中也有一組 __isset, __unset 。問題就來了,為何 offsetExists, offsetUnset 不是 magic methods ;或者反過來說,為何要有 magic methods?

這不免令人感到混亂。
未留名 (#comment-11071499)
Thu, 28 Jun 2007 11:39:12 +0800
無意和您爭論或造成筆戰~
但您前上述二個論點, 已流於個人主觀意識了..
如: 為什麼 ABC 語言要設計成 CDE 才能做到 DEF 的功能.
每個語言都有它的語言特性. 就如同我們在 delphi 寫一個簡單的 .pas 需要有
unit uses type var implementation end 等 block.
以 ruby 來看, 很麻煩又不直覺? 但這不就是這個語言的特性.

僅回應您最後一個論點.
http://www.php.net/manual/en/language.oop5.magic.php
http://www.php.net/manual/en/language.oop5.overloading.php
它們都是 Class Member method. 而 ArrayAccess 它是一個 interface.
您的問題變成是為什麼可以寫成 member method(magic method), 還要有個實作介面的方法.

請假設一下有一天, 我們買了 3rd-party 的 library 來開發專案,
而這個 library 是不提供 source code 亦或 source code 大到我們無能力去一一閱讀它.
(這個在(java/delphi)買元件常發生, 或許 php/ruby 目前還很少人賣 encode 過的 library)

我們僅在自己的程式用到它, 如 function ABC ($obj) 需要用到 3rd-party 傳入的 $obj,
如果我去看它的 source code 或它提供說明文件有清楚說明, 我怎麼知道原來它有利用 magic method,
所以我可以很方便的利用 $obj[index] 來操作它?

然而利用 interface , 我的程式改成, function ABC (ArrayAccess $obj) , 只要傳入 ABC 的
$obj, 我都一定能以 $obj[index] 來操作它.
未留名 (#comment-11075521)
Thu, 28 Jun 2007 17:47:26 +0800
呵呵,我們愈來愈接近 PHP 的斷層了。

整理整理,到《magic methods and interface》繼續。