今天我的老闆交代我在 Server 上裝一份新的 SugarCRM ,原以為是個很簡單的事情,結果花了一整天~
原因出在 SugarCRM 在安裝過程中,檢查 MySQL 連線設定那部份一直過不了,可是在同一台機器上,另外一份之前安裝過的 SugarCRM 卻跑的好好的~
我以為是 PHP 版本問題,從 PHP4 升級、換成 PHP5 都不行~
後來以為是 MySQL 的問題,重裝、換了 5.1 的版本也不行~
最後只好使出最終奧義:在 Windows 上裝好後再移過去...
這下終於可以動了,不過我還是不曉得 SugarCRM 的安裝程式出了什麼問題。
另外,我在 Windows 下安裝程序最後會發生 500 錯誤,只要把 SugarCRM 目錄下的 .htaccess 這個檔案刪除即可正常執行~
2008/04/25
2008/04/15
重構插件類別
算是在實做過程中發現一些問題,然後重構這個強力工具!
我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~
這幾天一直為了unset前後記憶用量沒有改變的問題無法釋懷,後來問了 kiang,他表示那是 Zend 引擎還沒到記憶體回收的週期,所以不會釋放~
這個類別的 __更新() 方法有一個地方我一直無法瞭解為何會有這個效果,知道的網友請開示吧~
另外一提,ADODB Lite 目前仍然是記憶用量最小的 DB Layer ,我自己寫的這個 DB Layer 跟它比較,兩邊都不掛任何多餘的模組,硬是比它大了約 50 K...
我該檢討了~
<?php
abstract class Zyme_Class_Plugin{
private $_插件 = array();
private $_方法 = array();
private $_反映 = array();
function __construct($宿主 = null){
static $類別 = __CLASS__;
if ($宿主 instanceof $類別) {
$this->__插件($宿主);
}
}
final function __call($方法, $參數){
return call_user_func_array($this->_方法[$方法], $參數);
}
// 清除插件方法
final protected function __清除(){
$this->_插件 = array();
$this->_方法 = array();
$this->_反映 = array();
}
// 測試某個插件是否已安裝
final protected function __已裝($類別){
return isset($this->_插件[$類別]);
}
// 將插件的方法加入$this的方法中
final protected function __插件(Zyme_Class_Plugin $插件){
$類別 = get_class($插件);
if (false == $this->__已裝($類別)){
$this->_插件[$類別] = $插件;
$this->_方法 = $插件->__反映() + $this->_方法;
}
}
// 取得插件的可呼叫方法列表
final function __方法(){
return $this->_方法;
}
// 取得插件本身的方法列表(除了方法名稱開頭是'__'的方法,例如一些魔術方法,或是方法本身屬於私有方法)
final private function __反映(){
$輸出 = &$this->_反映;
if (false == empty($輸出)) {
return $輸出;
}
$反映 = new ReflectionObject($this);
$方法 = $反映->getMethods();
foreach ($方法 as $項目){
$名稱 = $項目->getName();
if (0 !== strpos($名稱, '__') && false == $項目->isPrivate()) {
$輸出[$名稱] = array($this, $名稱);
}
}
return $輸出;
}
// 匯入插件的可呼叫方法表
final function __匯入(Zyme_Class_Plugin $宿主){
$this->_方法 = $宿主->__方法() + $this->_方法;
}
// 更新所有插件的方法,通常在載入所有插件後調用
final protected function __更新(){
foreach ($this->_插件 as $插件){
$插件->_方法 = $this->_方法 + $插件->_方法; // 照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行
// $插件->__匯入($this); // 萬一未來版本上面那行無法執行時,可以改用這行
}
}
}
?>
我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~
這幾天一直為了unset前後記憶用量沒有改變的問題無法釋懷,後來問了 kiang,他表示那是 Zend 引擎還沒到記憶體回收的週期,所以不會釋放~
這個類別的 __更新() 方法有一個地方我一直無法瞭解為何會有這個效果,知道的網友請開示吧~
另外一提,ADODB Lite 目前仍然是記憶用量最小的 DB Layer ,我自己寫的這個 DB Layer 跟它比較,兩邊都不掛任何多餘的模組,硬是比它大了約 50 K...
我該檢討了~
<?php
abstract class Zyme_Class_Plugin{
private $_插件 = array();
private $_方法 = array();
private $_反映 = array();
function __construct($宿主 = null){
static $類別 = __CLASS__;
if ($宿主 instanceof $類別) {
$this->__插件($宿主);
}
}
final function __call($方法, $參數){
return call_user_func_array($this->_方法[$方法], $參數);
}
// 清除插件方法
final protected function __清除(){
$this->_插件 = array();
$this->_方法 = array();
$this->_反映 = array();
}
// 測試某個插件是否已安裝
final protected function __已裝($類別){
return isset($this->_插件[$類別]);
}
// 將插件的方法加入$this的方法中
final protected function __插件(Zyme_Class_Plugin $插件){
$類別 = get_class($插件);
if (false == $this->__已裝($類別)){
$this->_插件[$類別] = $插件;
$this->_方法 = $插件->__反映() + $this->_方法;
}
}
// 取得插件的可呼叫方法列表
final function __方法(){
return $this->_方法;
}
// 取得插件本身的方法列表(除了方法名稱開頭是'__'的方法,例如一些魔術方法,或是方法本身屬於私有方法)
final private function __反映(){
$輸出 = &$this->_反映;
if (false == empty($輸出)) {
return $輸出;
}
$反映 = new ReflectionObject($this);
$方法 = $反映->getMethods();
foreach ($方法 as $項目){
$名稱 = $項目->getName();
if (0 !== strpos($名稱, '__') && false == $項目->isPrivate()) {
$輸出[$名稱] = array($this, $名稱);
}
}
return $輸出;
}
// 匯入插件的可呼叫方法表
final function __匯入(Zyme_Class_Plugin $宿主){
$this->_方法 = $宿主->__方法() + $this->_方法;
}
// 更新所有插件的方法,通常在載入所有插件後調用
final protected function __更新(){
foreach ($this->_插件 as $插件){
$插件->_方法 = $this->_方法 + $插件->_方法; // 照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行
// $插件->__匯入($this); // 萬一未來版本上面那行無法執行時,可以改用這行
}
}
}
?>
2008/04/07
開發平台暫時維持在 PHP 5.2.5
由於名稱空間的諸多限制,以及 PHP 5.3 的 call_user_func_array 傳遞參照參數陣列 與 &new 的 Deprecated 警告問題,個人決定還是先將開發平台維持在 PHP 5.2.5 上面。
名稱空間的限制還好,但後面那兩個會造成許多現有的函式庫噴出一堆警告訊息,我沒時間一個一個去修,所以只好暫時放棄,等年底 PHP 5.3 出來一陣子後再看看。
名稱空間的限制還好,但後面那兩個會造成許多現有的函式庫噴出一堆警告訊息,我沒時間一個一個去修,所以只好暫時放棄,等年底 PHP 5.3 出來一陣子後再看看。
2008/04/03
名稱空間的注意事項
在使用上有幾個要注意的事情:
最明顯的影響是 interface 一詞,這在 ZF 的命名中是非常常見的,目前的解法是加底線、使用縮寫,或是改用其他的詞彙。
不過 interface 這個詞彙是電腦的專有名詞,目前在物件導向中,並無其他的詞彙可替代,實在是很傷腦筋。
- 使用 use 敘述必須至少有一項用::串接
use test; // 這是錯的
use test::test1; // OK
- 上述的的敘述中,若用::來分隔,最後一項不可相同,若相同則必須用 as 來設定別名
use test::test1::test;
use test::test2::test; // 這是錯的
use test::test2::test as test0; // OK
- 命名空間不可使用關鍵字或保留字
use test::class; // 這是錯的
use test::_class; // OK
- 透過字串變數來 new 一個物件時,字串變數必須為完整的類別
use test::test1;這當中我個人覺得最嚴重的問題是,命名空間不可以使用關鍵字或保留字這項限制,如此一來將可用的詞彙縮減掉了,實在是很不方便~
$class1 = 'test1::_class';
$class2 = 'test::test1::_class';
$obj1 = new $class1(); // 這是錯的
$obj2 = new $class2(); // OK
最明顯的影響是 interface 一詞,這在 ZF 的命名中是非常常見的,目前的解法是加底線、使用縮寫,或是改用其他的詞彙。
不過 interface 這個詞彙是電腦的專有名詞,目前在物件導向中,並無其他的詞彙可替代,實在是很傷腦筋。
PHP 5.3 dev
根據 PHP 5.3 todo 的資訊,PHP 5.3 會在今年第二或是第三季推出,目前我正在考慮改用 5.3 的 namespace 功能加上類似ZF和PEAR的目錄結構來發展與佈署程式。
我放了一份修改過的 PortableAPM 在這裡,需要的人請自行取用。
使用時要注意 mysql 的部份,由於新引進 mysqlnd 的關係,所以即便是可以用 dl 來載入,對於 mysql 相關的 extension 最好在 php.ini 裡先載入。
剛剛找到這個網頁,裡面的資訊表示了PEAR2要採用名稱空間的作法。
我放了一份修改過的 PortableAPM 在這裡,需要的人請自行取用。
使用時要注意 mysql 的部份,由於新引進 mysqlnd 的關係,所以即便是可以用 dl 來載入,對於 mysql 相關的 extension 最好在 php.ini 裡先載入。
剛剛找到這個網頁,裡面的資訊表示了PEAR2要採用名稱空間的作法。
訂閱:
文章 (Atom)