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

首頁(yè) php教程 php手冊(cè) 用php實(shí)作一個(gè)簡(jiǎn)單的鍊式操作

用php實(shí)作一個(gè)簡(jiǎn)單的鍊式操作

Nov 30, 2016 pm 11:59 PM

最近在讀《php核心技術(shù)與最佳實(shí)踐》這本書(shū),書(shū)中第一章提到用__call()方法可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的字符串鍊式操作,比如,下面這個(gè)過(guò)濾字符串然後再求長(zhǎng)度的操作,一般要這麼寫(xiě):

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

那麼能否實(shí)現(xiàn)下面這種寫(xiě)法呢?

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

下面就來(lái)試試。

鍊式操作,說(shuō)白了其實(shí)就是鍊式的呼叫物件的方法。既然要實(shí)作字串的鍊式操作,那麼就要實(shí)作一個(gè)字串類(lèi),然後再對(duì)這個(gè)類(lèi)的物件進(jìn)行呼叫操作。我對(duì)字串類(lèi)別的期望如下:(1)當(dāng)我建立物件時(shí),我可以將字串賦值給物件的屬性,並且可以存取這個(gè)屬性讀取值;(2)我可以呼叫trim() 和strlen( )方法;(3)我還可以這麼呼叫方法$str->trim()->strlen()。

上面的第(1)條,是一個(gè)字串類(lèi)別的基本要求。先把這個(gè)實(shí)現(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()實(shí)作了,參考書(shū)中的想法:觸發(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> }

測(cè)試下:

<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, $name, $this

->value函數(shù)的名字(這裡也就是trim),後面兩個(gè)是回呼函數(shù)(tirm)的參數(shù),參數(shù)的順序不要弄顛倒了。 $args是數(shù)組,也需要注意下。

第2條還要實(shí)作strlen(),這時(shí)上面程式碼中的第13行就很關(guān)鍵了:?return $this;

?它的作用就是,在第12行呼叫trim()處理完字串後重新value屬性賦值,再傳回目前物件的引用,這樣物件內(nèi)的其他方法就可以對(duì)屬性value進(jìn)行連續(xù)運(yùn)算了,也就實(shí)作了鍊式運(yùn)算。 $str->strlen()實(shí)作如下:
<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> }

測(cè)試下:
<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é)果:

鍊式操作:
<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é)果:

?

到這裡,這篇文章本來(lái)就結(jié)束了。但是,我想了下,其實(shí)不用__call()方法,也是可以實(shí)作鍊式運(yùn)算的。下面是不用__call()的實(shí)作:
<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> }

鍊式操作的關(guān)鍵是做完操作後要return $this。

另外,本文受到園子裡這篇文章的啟發(fā),用call_user_func_array()替換了call_user_func()實(shí)現(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()方法效果是相同的,這樣程式碼似乎比之前的實(shí)作更優(yōu)雅。

總結(jié):

__call()在物件呼叫一個(gè)不可存取的方法時(shí)會(huì)被觸發(fā),所以可以實(shí)作類(lèi)別的動(dòng)態(tài)方法的創(chuàng)建,實(shí)作php的方法重載功能,但它其實(shí)是一個(gè)語(yǔ)法糖(__construct()方法也是)。

那麼如果沒(méi)有__call()等語(yǔ)法糖,能否實(shí)現(xiàn)動(dòng)態(tài)方法的創(chuàng)建和鍊式操作呢?我想會(huì)涉及到以下幾個(gè)方面的問(wèn)題:類(lèi)別方法是否存在和可以調(diào)用,這個(gè)可以用method_exists、is_callable、get_class_methods等方法來(lái)實(shí)現(xiàn),另外,就是在創(chuàng)建對(duì)象時(shí)給屬性賦值(初始化),這個(gè)語(yǔ)法糖確實(shí)方便,不過(guò)不是必要的。等有時(shí)間再研究下吧。

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

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

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整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門(mén)話題

Laravel 教程
1597
29
PHP教程
1488
72