2011-07-14 11 views
-1

静的クラスの継承を実装するベストプラクティス? PHPマニュアルから(シングルトン)

は[...] staticメソッドの呼び出しは、コンパイル時に解決されています。 明示的なクラス名を使用する場合、メソッドはすでに完全に識別されており、 継承規則は適用されません。呼び出しが自己によって行われた場合、selfは (現在のクラス、すなわちコードが属するクラス)に変換されます。ここ も何の継承ルールは適用されません[...]

への道を探して..soイムは、静的なシングルトンと標準 OOPの継承をエミュレートします。

コードは、より良い説明:

// 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

*(関連)* [Staticは有害とみなされます](http://kore-nordmann.de/blog /0103_static_considered_harmful.html) – Gordon

答えて

4

PHPでSingletonパターンは、このようなものです:

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

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

これです:あなたのために

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が、これがあることが重要ですあなたが探している?

+0

はい、私は 'new static();'がありませんでした。 ありがとう、あなたは私の一日を作った! – Strae

+0

完全な答えは重要です。遅い静的バインディング機能は、PHP 5.3以降で提供されています。http://php.net/manual/en/language.oop5.late-static-bindings.php。 –

+0

@Gordon完了。 –

関連する問題