2011-07-14 82 views
-1

從php手冊:實現靜態類繼承的最佳實踐? (singleton)

[...]靜態方法調用在編譯時解析。 使用明確的類名稱時,該方法已被完全標識,並且不會應用繼承規則。如果通話是通過自我完成的,那麼self會被轉換爲當前類別 ,即代碼所屬的類別。 這裏也沒有繼承規則[...]

..所以尋找一種方式來IM效仿標準接力傳承與靜態單。

代碼更好地解釋:

// Normal inheritance: my goal. 
class Foo{ 
    public function test(){ 
     echo "Foo->test()\n"; 
    } 
} 

class Bar extends Foo{ 
    public function other_test() 
    { 
     echo "Bar->other_test()\n"; 
    } 
} 


$obj = new Bar(); 
echo get_class($obj) . "\n"; 
$obj->test(); 
$obj->other_test(); 
/* 
Output: 
Bar 
Foo->test() 
Bar->other_test() 
*/ 


// How i would love to do: 
class Foo2{ 
    public static function test2() 
    { 
     echo "Foo2::test2()\n"; 
    } 

    // Singleton? 
    public static $_instance; 
    public static function get_instance() 
    { 
     if(is_null(self::$_instance)) 
     { 
      self::$_instance = new self(); 
     } 
     return self::$_instance; 
    } 
} 

class Bar2 extends Foo2{ 
    public static function other_test2() 
    { 
     echo "Bar2::other_test2()\n"; 
    } 
} 

$obj2 = Bar2::get_instance(); 
echo get_class($obj2) . "\n"; 
$obj2::test2(); 
$obj2::other_test2(); 
/* 
Output: 
Foo2 
Foo2::test2() 
Fatal error: Call to undefined method Foo2::other_test2() 
*/ 

echo "\n-------\n"; 

// How im doing actually: 
interface Foo3{ 
    public static function get_instance(); 
} 

class Bar3 implements Foo3{ 
    // Singleton? 
    public static $_instance; 
    public static function get_instance() 
    { 
     if(is_null(self::$_instance)) 
     { 
      self::$_instance = new self(); 
     } 
     return self::$_instance; 
    } 
    public static function test3() 
    { 
     echo "Bar3::test3()\n"; 
    } 
    public static function other_test3() 
    { 
     echo "Bar3::other_test3()\n"; 
    } 
} 


$obj3 = Bar3::get_instance(); 
echo get_class($obj3) . "\n"; 
$obj3::test3(); 
$obj3::other_test3(); 
/* 
Output: 
Bar3 
Foo3::test3() 
Bar3::other_test3() 
*/ 

最後的「路」逼我避免get_instance和靜態變量被放置在父類,所以我不認爲這是一個最好的解決辦法。如果由於某種原因,我get_instance()功能將改變未來,我不希望編輯所有類(繼承!繼承!我們都希望繼承!

那麼,有沒有一種方法或最佳實踐來解決這個問題?

PS:php5.3.2

+2

[不要使用單身人士](http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html) –

+0

*(相關)* [誰需要單身人士](http://stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323) – Gordon

+0

*(相關)* [靜態認爲有害](http://kore-nordmann.de/blog /0103_static_considered_harmful.html) – Gordon

回答

4

PHP中的Singleton模式是這樣的:

class Singleton { 
    private static $instance = null; 

    // Constructor is private, so class cannot be instantiazed from outside 
    private function __construct() { 
    } 

    public static function getInstance() { 
     if (static::$instance === null) { 
       static::$instance = new Singleton(); 
     } 
     return static::$instance; 
    } 

    public static function test() { 
     echo 'Singleton::test()'; 
    } 

    public function __sleep() { 
     throw new Exception('Serialization is not alowed.'); 
    } 

    public function __wakeup() { 
     throw new Exception('Serialization is not alowed.'); 
    } 

    public function __clone() { 
     throw new Exception('Cloning is not alowed.'); 
    } 
} 

對你來說是重要的關鍵字static,那麼這個:

class B extends Singleton { 
    public static function test2() { 
     echo 'B::test2()'; 
    } 
} 

$b = B::getInstance(); 
B::test(); 
B::test2(); 
// Singleton::test() 
// B::test() 

這是你在找什麼?

+0

是的,我錯過了'new static();'。 感謝隊友,你讓我的一天! – Strae

+0

對於完整的答案很重要的一點很重要,那就是PHP 5.3後期的靜態綁定特性,以及更多信息可以在這裏找到:http://php.net/manual/en/language.oop5.late-static-bindings.php。 –

+0

@戈登完成。 –