2011-07-14 84 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

@戈登完成。 –