亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 php教程 php手冊 用php實現(xiàn)一個簡單的鏈?zhǔn)讲僮?/span>

用php實現(xiàn)一個簡單的鏈?zhǔn)讲僮?/h1> Nov 30, 2016 pm 11:59 PM


最近在讀《php核心技術(shù)與最佳實踐》這本書,書中第一章提到用__call()方法可以實現(xiàn)一個簡單的字符串鏈?zhǔn)讲僮?,比如,下面這個過濾字符串然后再求長度的操作,一般要這么寫:

<span style="color: #008080;">strlen</span>(<span style="color: #008080;">trim</span>(<span style="color: #800080;">$str</span>));

那么能否實現(xiàn)下面這種寫法呢?

<span style="color: #800080;">$str</span>-><span style="color: #008080;">trim</span>()-><span style="color: #008080;">strlen</span>();

下面就來試下。

鏈?zhǔn)讲僮?,說白了其實就是鏈?zhǔn)降恼{(diào)用對象的方法。既然要實現(xiàn)字符串的鏈?zhǔn)讲僮?,那么就要實現(xiàn)一個字符串類,然后對這個類的對象進(jìn)行調(diào)用操作。我對字符串類的期望如下:(1)當(dāng)我創(chuàng)建對象時,我可以將字符串賦值給對象的屬性,并且可以訪問這個屬性讀取值;(2)我可以調(diào)用trim() 和strlen()方法;(3)我還可以這么調(diào)用方法$str->trim()->strlen()。

上面的第(1)條,是一個字符串類的基本要求。先把這個實現(xiàn)了:

<span style="color: #008080;">1</span> <span style="color: #0000ff;">class</span> <span style="color: #0000ff;">String</span>
<span style="color: #008080;">2</span> <span style="color: #000000;">{
</span><span style="color: #008080;">3</span>     <span style="color: #0000ff;">public</span> <span style="color: #800080;">$value</span><span style="color: #000000;">;
</span><span style="color: #008080;">4</span> 
<span style="color: #008080;">5</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$str</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;">6</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">7</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #800080;">$str</span><span style="color: #000000;">;
</span><span style="color: #008080;">8</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">9</span> }

可以試下:

<span style="color: #008080;">1</span> <span style="color: #800080;">$str</span> = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">String</span>('01389'<span style="color: #000000;">);
</span><span style="color: #008080;">2</span> <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$str</span>->value;

然后再看第2條,先把$str->trim()實現(xiàn)了,參考書中的思路:觸發(fā)__call方法然后執(zhí)行call_user_func。代碼如下:

<span style="color: #008080;"> 1</span> <span style="color: #0000ff;">class</span> <span style="color: #0000ff;">String</span>
<span style="color: #008080;"> 2</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 3</span>     <span style="color: #0000ff;">public</span> <span style="color: #800080;">$value</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 4</span> 
<span style="color: #008080;"> 5</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$str</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">    {
</span><span style="color: #008080;"> 7</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #800080;">$str</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 8</span> <span style="color: #000000;">    }
</span><span style="color: #008080;"> 9</span> 
<span style="color: #008080;">10</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __call(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$args</span><span style="color: #000000;">)
</span><span style="color: #008080;">11</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">12</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #008080;">call_user_func</span>(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$this</span>->value, <span style="color: #800080;">$args</span>[0<span style="color: #000000;">]);
</span><span style="color: #008080;">13</span>         <span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span><span style="color: #000000;">;
</span><span style="color: #008080;">14</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">15</span> }

測試下:

<span style="color: #008080;">1</span> <span style="color: #800080;">$str</span> = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">String</span>('01389'<span style="color: #000000;">);
</span><span style="color: #008080;">2</span> <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$str</span>-><span style="color: #008080;">trim</span>('0')->value;

結(jié)果如下:

上面需要注意的是第12行:?$this->value = call_user_func($name, $this->value, $args[0]);?$name是回調(diào)函數(shù)的名字(這里也就是trim),后面兩個是回調(diào)函數(shù)(tirm)的參數(shù),參數(shù)的順序不要弄顛倒了。$args是數(shù)組,也需要注意下。

第2條中還要實現(xiàn)strlen(),這時上面代碼中的第13行就很關(guān)鍵了:?return $this;?它的作用就是,在第12行調(diào)用trim()處理完字符串后重新value屬性賦值,然后返回當(dāng)前對象的引用,這樣對象內(nèi)的其他方法就可以對屬性value進(jìn)行連續(xù)操作了,也就實現(xiàn)了鏈?zhǔn)讲僮鳌?str->strlen()實現(xiàn)如下:

<span style="color: #008080;"> 1</span> <span style="color: #0000ff;">class</span> <span style="color: #0000ff;">String</span>
<span style="color: #008080;"> 2</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 3</span>     <span style="color: #0000ff;">public</span> <span style="color: #800080;">$value</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 4</span> 
<span style="color: #008080;"> 5</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$str</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">    {
</span><span style="color: #008080;"> 7</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #800080;">$str</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 8</span> <span style="color: #000000;">    }
</span><span style="color: #008080;"> 9</span> 
<span style="color: #008080;">10</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __call(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$args</span><span style="color: #000000;">)
</span><span style="color: #008080;">11</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">12</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #008080;">call_user_func</span>(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$this</span>->value, <span style="color: #800080;">$args</span>[0<span style="color: #000000;">]);
</span><span style="color: #008080;">13</span>         <span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span><span style="color: #000000;">;
</span><span style="color: #008080;">14</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">15</span> 
<span style="color: #008080;">16</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">strlen</span><span style="color: #000000;">()
</span><span style="color: #008080;">17</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">18</span>         <span style="color: #0000ff;">return</span> <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">value);
</span><span style="color: #008080;">19</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">20</span> }

測試下:

<span style="color: #008080;">1</span> <span style="color: #800080;">$str</span> = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">String</span>('01389'<span style="color: #000000;">);
</span><span style="color: #008080;">2</span> <span style="color: #0000ff;">echo</span> <span style="color: #800080;">$str</span>-><span style="color: #008080;">strlen</span>();

結(jié)果:

鏈?zhǔn)讲僮鳎?/p>

<span style="color: #0000ff;">echo</span> <span style="color: #800080;">$str</span>-><span style="color: #008080;">trim</span>('0')-><span style="color: #008080;">strlen</span>();

結(jié)果:

?


到這里,這篇文章本該就結(jié)束了。但是,我想了下,其實不用__call()方法,也是可以實現(xiàn)鏈?zhǔn)讲僮鞯?。下面是不用__call()的實現(xiàn):

<span style="color: #008080;"> 1</span> <span style="color: #0000ff;">class</span> <span style="color: #0000ff;">String</span>
<span style="color: #008080;"> 2</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 3</span>     <span style="color: #0000ff;">public</span> <span style="color: #800080;">$value</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 4</span> 
<span style="color: #008080;"> 5</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$str</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">    {
</span><span style="color: #008080;"> 7</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #800080;">$str</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 8</span> <span style="color: #000000;">    }
</span><span style="color: #008080;"> 9</span> 
<span style="color: #008080;">10</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">trim</span>(<span style="color: #800080;">$t</span><span style="color: #000000;">)
</span><span style="color: #008080;">11</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">12</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #008080;">trim</span>(<span style="color: #800080;">$this</span>->value, <span style="color: #800080;">$t</span><span style="color: #000000;">);
</span><span style="color: #008080;">13</span>         <span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span><span style="color: #000000;">;
</span><span style="color: #008080;">14</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">15</span> 
<span style="color: #008080;">16</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">strlen</span><span style="color: #000000;">()
</span><span style="color: #008080;">17</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">18</span>         <span style="color: #0000ff;">return</span> <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">value);
</span><span style="color: #008080;">19</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">20</span> }

鏈?zhǔn)讲僮鞯年P(guān)鍵是在做完操作后要return $this。

另外,本文受到園子里這篇文章的啟發(fā),用call_user_func_array()替換了call_user_func()實現(xiàn),將__call()方法修改如下。

<span style="color: #008080;">1</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __call(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$args</span><span style="color: #000000;">)
</span><span style="color: #008080;">2</span> <span style="color: #000000;">    {
</span><span style="color: #008080;">3</span>         <span style="color: #008080;">array_unshift</span>(<span style="color: #800080;">$args</span>, <span style="color: #800080;">$this</span>-><span style="color: #000000;">value);
</span><span style="color: #008080;">4</span>         <span style="color: #800080;">$this</span>->value = <span style="color: #008080;">call_user_func_array</span>(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$args</span><span style="color: #000000;">);
</span><span style="color: #008080;">5</span>         <span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span><span style="color: #000000;">;
</span><span style="color: #008080;">6</span>     }

與上面的__call()方法效果是相同的,這樣代碼似乎比之前的實現(xiàn)要優(yōu)雅些。


總結(jié):

__call()在對象調(diào)用一個不可訪問的方法時會被觸發(fā),所以可以實現(xiàn)類的動態(tài)方法的創(chuàng)建,實現(xiàn)php的方法重載功能,但它其實是一個語法糖(__construct()方法也是)。

那么如果沒有__call()等語法糖,能否實現(xiàn)動態(tài)方法的創(chuàng)建和鏈?zhǔn)讲僮髂??我想會涉及到以下幾個方面的問題:類方法是否存在和可以調(diào)用,這個可以用method_exists、is_callable、get_class_methods等方法來實現(xiàn),另外,就是在創(chuàng)建對象時給屬性賦值(初始化),這個語法糖確實方便,不過不是必需的。等有時間再研究下吧。

?

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72