简体   繁体   中英

Best practice to implement static class inheritance? (singleton)

From php manual:

[...] Static method calls are resolved at compile time. When using an explicit class name the method is already identified completely and no inheritance rules apply. If the call is done by self then self is translated to the current class, that is the class the code belongs to. Here also no inheritance rules apply [...]

..so im looking for a way to emulate the standard oop inheritance with static singleton.

Code explain better:

// 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()
*/

The last 'way' force me to avoid the get_instance and static variables to be placed in the parent class, so I do not consider it as a best solution.. if for some reason my get_instance() function will change in the future, i dont want to edit all classes ( inheritance! inheritance! we all want inheritance! )

So, is there a way or a best practices to solve this problem?

ps: php5.3.2

The Singleton pattern in PHP is something like this:

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.');
     }
}

For you is important that keyword static , then this:

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

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

Is this you looking for?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM