欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

php5.3后靜態(tài)綁定用法詳解

 更新時(shí)間:2016年11月11日 10:02:13   作者:codes  
這篇文章主要介紹了php5.3后靜態(tài)綁定用法,結(jié)合具體示例分析了php5.3開(kāi)始引入的后靜態(tài)綁定相關(guān)概念、功能、使用方法與注意事項(xiàng),并搜集了來(lái)自網(wǎng)友的典型分析說(shuō)明,需要的朋友可以參考下

本文實(shí)例講述了php5.3后靜態(tài)綁定用法。分享給大家供大家參考,具體如下:

手冊(cè)原文:

自 PHP 5.3.0 起,PHP 增加了一個(gè)叫做后期靜態(tài)綁定的功能,用于在繼承范圍內(nèi)引用靜態(tài)調(diào)用的類。

準(zhǔn)確說(shuō),后期靜態(tài)綁定工作原理是存儲(chǔ)了在上一個(gè)"非轉(zhuǎn)發(fā)調(diào)用"(non-forwarding call)的類名。當(dāng)進(jìn)行靜態(tài)方法調(diào)用時(shí),該類名即為明確指定的那個(gè)(通常在 :: 運(yùn)算符左側(cè)部分);當(dāng)進(jìn)行非靜態(tài)方法調(diào)用時(shí),即為該對(duì)象所屬的類。所謂的"轉(zhuǎn)發(fā)調(diào)用"(forwarding call)指的是通過(guò)以下幾種方式進(jìn)行的靜態(tài)調(diào)用:self::,parent::,static:: 以及 forward_static_call()??捎?get_called_class() 函數(shù)來(lái)得到被調(diào)用的方法所在的類名,static:: 則指出了其范圍

該功能從語(yǔ)言內(nèi)部角度考慮被命名為"后期靜態(tài)綁定"。"后期綁定"的意思是說(shuō),static:: 不再被解析為定義當(dāng)前方法所在的類,而是在實(shí)際運(yùn)行時(shí)計(jì)算的。也可以稱之為"靜態(tài)綁定",因?yàn)樗梢杂糜冢ǖ幌抻冢╈o態(tài)方法的調(diào)用。

self:: 的限制

使用 self:: 或者 __CLASS__ 對(duì)當(dāng)前類的靜態(tài)引用,取決于定義當(dāng)前方法所在的類:

Example #1 self:: 用法

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?> 

以上例程會(huì)輸出:

A

后期靜態(tài)綁定的用法 后期靜態(tài)綁定本想通過(guò)引入一個(gè)新的關(guān)鍵字表示運(yùn)行時(shí)最初調(diào)用的類來(lái)繞過(guò)限制。簡(jiǎn)單地說(shuō),這個(gè)關(guān)鍵字能夠讓你在上述例子中調(diào)用 test() 時(shí)引用的類是 B 而不是 A。最終決定不引入新的關(guān)鍵字,而是使用已經(jīng)預(yù)留的 static 關(guān)鍵字。

Example #2 static:: 簡(jiǎn)單用法

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期靜態(tài)綁定從這里開(kāi)始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?> 

以上例程會(huì)輸出:

B

Note: 在非靜態(tài)環(huán)境下,所調(diào)用的類即為該對(duì)象實(shí)例所屬的類。由于 $this-> 會(huì)在同一作用范圍內(nèi)嘗試調(diào)用私有方法,而 static:: 則可能給出不同結(jié)果。另一個(gè)區(qū)別是 static:: 只能用于靜態(tài)屬性。

Example #3 非靜態(tài)環(huán)境下使用 static::

<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //fails
?> 

以上例程會(huì)輸出:

success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

Note: 后期靜態(tài)綁定的解析會(huì)一直到取得一個(gè)完全解析了的靜態(tài)調(diào)用為止。另一方面,如果靜態(tài)調(diào)用使用 parent:: 或者 self:: 將轉(zhuǎn)發(fā)調(diào)用信息。

Example #4 轉(zhuǎn)發(fā)和非轉(zhuǎn)發(fā)調(diào)用

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?> 

以上例程會(huì)輸出:

A
C
C

下面示例分析了基于PHP后期靜態(tài)綁定功能解決在繼承范圍內(nèi)引用靜態(tài)調(diào)用的類。

先看如下代碼:

class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is alive

很明顯,結(jié)果不是我們預(yù)期的,這是因?yàn)閟elf::取決于定義時(shí)所在的類,而不是運(yùn)行中的類。為了解決這個(gè)問(wèn)題,你可能會(huì)在繼承類中重寫(xiě)status()方法,更好的解決方案是PHP 5.3后添加了后期靜態(tài)綁定的功能。

代碼如下:

class Person
{
public static function status()
{
static::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is deceased

可見(jiàn),static::不在指向當(dāng)前所在的類,實(shí)際上,它是在運(yùn)行中計(jì)算的,強(qiáng)制獲取最終類的所有屬性。

因此,建議,以后不要再使用self::,使用static::

補(bǔ)充:

網(wǎng)友帖1

php的后期靜態(tài)綁定,怎么解釋?下面的這幅圖輸出是A,C,C

由圖的繼承關(guān)系可知:C徹底包含了B和A。

在看答案結(jié)果以前,他細(xì)觀察發(fā)現(xiàn),三個(gè)類里都有同一個(gè)名稱who()方法。
系統(tǒng)會(huì)用最后一個(gè)優(yōu)先級(jí)最高,進(jìn)一步的說(shuō),你幾乎沒(méi)法通過(guò)C去調(diào)用A、B內(nèi)的who(),只能重改方法,比如添加個(gè)getBWho(){echo B::who();}
然后通過(guò)C::getBWho();來(lái)調(diào)用B內(nèi)的who();

下面來(lái)看運(yùn)行結(jié)果:

test只在B中出現(xiàn),所以結(jié)果必然是test()中運(yùn)行的三個(gè)結(jié)果:

第一個(gè):靜態(tài)直接指名到姓的調(diào)用A內(nèi)靜態(tài)函數(shù),這沒(méi)有懸念,必然是A
第二個(gè):parent::是調(diào)用上一級(jí)的父類,在此題中為A,A中又直接調(diào)用static:who();上面說(shuō)過(guò)了,這個(gè)who()優(yōu)先級(jí)最高的在C里面,無(wú)論在你ABC中哪里調(diào)用,只要是static::who()必然是最后定義的那個(gè),覆蓋效應(yīng),如果想調(diào)用A里的必需指明A::who()或是通過(guò)去除static從作用域限制來(lái)實(shí)現(xiàn)。所以這個(gè)who()就是C中定義的who
第三個(gè):self::who與第二個(gè)類似的問(wèn)題,看樣該走B的,注意覆蓋效應(yīng),要想調(diào)用B內(nèi)的who必須得B::who(),因?yàn)楦呒?jí)的C已經(jīng)重寫(xiě)了這個(gè)方法,如果C中沒(méi)有who,肯定就是B,依次類推。所以必然還是調(diào)用C中的who;

所以答案為:ACC

代碼如下:

<?php
class A {
  public static function foo() {
    static::who();
  }
  public static function who() {
    echo __CLASS__."\n";
  }
}
class B extends A {
  public static function test() {
    A::foo();
    parent::foo();
    self::foo();
  }
  public static function who() {
    echo __CLASS__."\n";
  }
}
class C extends B {
  //public static function who() {
  //  echo __CLASS__."\n";
  //}
}
C::test();
?>

輸出為:A B B

網(wǎng)友帖2

(還是針對(duì)上面圖中的代碼)

手冊(cè)不是說(shuō)得很清楚么

”后期綁定“的意思是說(shuō),static::不再被解析為定義當(dāng)前方法所在的類,而是在實(shí)際運(yùn)行時(shí)計(jì)算的。也可以稱之為”靜態(tài)綁定“,因?yàn)樗梢杂糜冢ǖ幌抻冢╈o態(tài)方法的調(diào)用。

#1說(shuō)的有個(gè)小問(wèn)題

【self::foo(); // 這個(gè)self實(shí)際上是C類。明白嗎? C::test() C繼承了B的test()方法】

不準(zhǔn)確,self還是B類,但是本身沒(méi)有覆寫(xiě)foo方法,所以就調(diào)用父類A的foo方法。

如果self實(shí)際是C類,那你試下self::foo();改成self::who();,應(yīng)當(dāng)打印C,但是打印B,這也正是self和static的區(qū)別。

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?>

輸出為:A C B

網(wǎng)友帖3

A::foo(); //A指代A類,訪問(wèn)A類的foo方法和who方法
parent::foo();//調(diào)用B類的父類——A的foo方法,并告訴foo方法最原始的調(diào)用者是C
self::foo(); //self指代定義該方法的類,即B,但是B沒(méi)有定義foo方法,它將原始的調(diào)用者C向上傳遞,
// 訪問(wèn)父類的foo方法,最后訪問(wèn)c的who方法;

所以這就回答了樓上的疑問(wèn):若是把self::foo(); 改成self::who(),因?yàn)閟elf指代B,而B(niǎo)有who方法,所以結(jié)果是變成了B

靜態(tài)調(diào)用使用 parent:: 或者 self:: 將轉(zhuǎn)發(fā)原始調(diào)用信息。

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《PHP網(wǎng)絡(luò)編程技巧總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總

希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評(píng)論