是否可以在PHP中创建静态类(如在C#中)?

时间:2009-01-22 10:30:58

标签: php design-patterns oop static

我想在PHP中创建一个静态类,并且它的行为与在C#中的行为类似,所以

  1. 首次调用类
  2. 时会自动调用构造函数
  3. 无需实例化
  4. 这种东西......

    static class Hello {
        private static $greeting = 'Hello';
    
        private __construct() {
            $greeting .= ' There!';
        }
    
        public static greet(){
            echo $greeting;
        }
    }
    
    Hello::greet(); // Hello There!
    

6 个答案:

答案 0 :(得分:190)

您可以在PHP中使用静态类,但它们不会自动调用构造函数(如果您尝试调用self::__construct(),则会出现错误)。

因此,您必须创建一个initialize()函数并在每个方法中调用它:

<?php

class Hello
{
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>

答案 1 :(得分:49)

除了Greg的答案之外,我还建议将构造函数设置为private,以便无法实例化该类。

所以在我看来,这是一个基于格雷格的更完整的例子:

<?php

class Hello
{
    /**
     * Construct won't be called inside this class and is uncallable from
     * the outside. This prevents instantiating this class.
     * This is by purpose, because we want a static class.
     */
    private function __construct() {}
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>

答案 2 :(得分:23)

你可以拥有那些“静态”类。但我认为,缺少一些非常重要的东西:在php中你没有应用程序循环,所以你不会在整个应用程序中获得真正的静态(或单例)...

请参阅Singleton in PHP

答案 3 :(得分:4)

final Class B{

    static $staticVar;
    static function getA(){
        self::$staticVar = New A;
    }
}

b的结构称为单例处理程序,您也可以在

中执行
Class a{
    static $instance;
    static function getA(...){
        if(!isset(self::$staticVar)){
            self::$staticVar = New A(...);
        }
        return self::$staticVar;
    }
}

这是单身人士使用$a = a::getA(...);

答案 4 :(得分:3)

我通常更喜欢编写常规的非静态类,并使用工厂类来实例化对象的单个(sudo静态)实例。

这样构造函数和析构函数按照惯例工作,如果我愿意,我可以创建其他非静态实例(例如第二个数据库连接)

我一直使用它,对于创建自定义DB存储会话处理程序特别有用,因为当页面终止析构函数时会将会话推送到数据库。

另一个优点是您可以忽略您调用的顺序,因为所有内容都将按需设置。

class Factory {
    static function &getDB ($construct_params = null)
    {
        static $instance;
        if( ! is_object($instance) )
        {
            include_once("clsDB.php");
            $instance = new clsDB($construct_params);   // constructor will be called
        }
        return $instance;
    }
}

数据库类......

class clsDB {

    $regular_public_variables = "whatever";

    function __construct($construct_params) {...}
    function __destruct() {...}

    function getvar() { return $this->regular_public_variables; }
}

您想要使用的任何地方只需致电...

$static_instance = &Factory::getDB($somekickoff);

然后将所有方法视为非静态(因为它们是)

echo $static_instance->getvar();

答案 5 :(得分:2)

对象无法静态定义 但这很有效。

final Class B{
  static $var;
  static function init(){
    self::$var = new A();
}
B::init();