最近在讀《php核心技術與最佳實踐》這本書,書中第一章提到用__call()方法可以實現乙個簡單的字串鏈式操作,比如,下面這個過濾字串然後再求長度的操作,一般要這麼寫:
strlen(trim($str));那麼能否實現下面這種寫法呢?
$str->trim()->strlen();下面就來試下。
鏈式操作,說白了其實就是鏈式的呼叫物件的方法。既然要實現字串的鏈式操作,那麼就要實現乙個字串類,然後對這個類的物件進行呼叫操作。我對字串類的期望如下:(1)當我建立物件時,我可以將字串賦值給物件的屬性,並且可以訪問這個屬性讀取值;(2)我可以呼叫trim() 和strlen()方法;(3)我還可以這麼呼叫方法$str->trim()->strlen()。
上面的第(1)條,是乙個字串類的基本要求。先把這個實現了:
1 class string可以試下:2 9 }
1 $str = new string('01389');2 echo $str->value;
1 class string測試下:2 9
10 public function __call($name, $args)
11 15 }
1 $str = new string('01389');結果如下:2 echo $str->trim('0')->value;
上面需要注意的是第12行: $this->value = call_user_func($name, $this->value, $args[0]); $name是**函式的名字(這裡也就是trim),後面兩個是**函式(tirm)的引數,引數的順序不要弄顛倒了。$args是陣列,也需要注意下。
第2條中還要實現strlen(),這時上面**中的第13行就很關鍵了: return $this; 它的作用就是,在第12行呼叫trim()處理完字串後重新value屬性賦值,然後返回當前物件的引用,這樣物件內的其他方法就可以對屬性value進行連續操作了,也就實現了鏈式操作。$str->strlen()實現如下:
1 class string測試下:2 9
10 public function __call($name, $args)
11 15
16 public function strlen()
17 20 }
1 $str = new string('01389');結果:2 echo $str->strlen();
鏈式操作:
echo $str->trim('0')->strlen();結果:
1 class string鏈式操作的關鍵是在做完操作後要return $this。2 9
10 public function trim($t)
11 15
16 public function strlen()
17 20 }
另外,本文受到園子裡這篇文章的啟發,用call_user_func_array()替換了call_user_func()實現,將__call()方法修改如下。
1 public function __call($name, $args)與上面的__call()方法效果是相同的,這樣**似乎比之前的實現要優雅些。2
總結:__call()在物件呼叫乙個不可訪問的方法時會被觸發,所以可以實現類的動態方法的建立,實現php的方法過載功能,但它其實是乙個語法糖(__construct()方法也是)。
那麼如果沒有__call()等語法糖,能否實現動態方法的建立和鏈式操作呢?我想會涉及到以下幾個方面的問題:類方法是否存在和可以呼叫,這個可以用method_exists、is_callable、get_class_methods等方法來實現,另外,就是在建立物件時給屬性賦值(初始化),這個語法糖確實方便,不過不是必需的。等有時間再研究下吧。
**
用php實現乙個簡單的守護程序,多程序
首先我們要知道建立守護程序的五個步驟 建立子程序,終止父程序 在子程序中建立新會話 改變工作目錄 預設繼承了父程序的當前工作目錄 重設檔案建立掩碼 預設繼承了父程序的檔案建立掩碼 關閉檔案描述符 預設繼承了父程序開啟了的檔案 還要安裝有pcntl擴充套件,可通過php m檢視是否安裝 然後直接上 f...
Php 鏈式執行,PHP實現鏈式操作的原理詳解
在乙個類中有多個方法,當你例項化這個類,並呼叫方法時只能乙個乙個呼叫,類似 db.php class db public function where code here public function order code here public function limit code here ...
php 路由實現 PHP實現乙個簡單url路由功能
game.weibo.com後面匹配到的項,指向了某個php頁面,然後根據引數獲取要訪問的遊戲應用標識,後資料庫或者快取裡查詢該應用標識,如果不存在則輸出錯誤提示,如果應用存在則載入遊戲應用鏈結位址。現在寫乙個php例子,假設我的ip為192.168.0.33,我加了一層名為router的路徑,之後...