【问题标题】:Can't access static class members of singleton [duplicate]无法访问单例的静态类成员[重复]
【发布时间】:2013-09-25 08:12:03
【问题描述】:

我有一个简单的单例类:

class controller {

    // Store the single instance of controller
    private static $_controller = null;
    public static $user;
    public static $db;
    public static $page;
    public static $code;

    // construct the class and set up the user & db instances
    private function __construct() {
        self::$db = new db(HOST, USER, PASS, DB);
        self::$user = new user();
        self::$page = new page();
        self::$code = new code();
    }

    // Getter method for creating/returning the single instance of this class
    public static function getInstance() {
        if (!self::$_controller) {                        
            self::$_controller = new self();
        }

        return self::$_controller;
    }
}

我这样调用(并测试)它:

$load = controller::getInstance();
print_r($load::$db->query('SELECT * FROM `users`'));

但是我从 PHP 中得到了这个错误:

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM

此代码适用于 PHP 5.3,但不适用于运行 PHP 5.2 的服务器

这是怎么回事?

【问题讨论】:

  • 请停止在您的代码中使用单例。此外,您可能会考虑到 php 5.3 已经有几个月不受支持(以及 5.2 - 超过 2 年前)。你真的应该更新你的服务器或转移到不同的主机。
  • 您的实例不应具有 $db$user$page$code 等静态属性。实例应该具有对象属性。
  • 这是您的确切代码的复制粘贴吗?这个错误通常意味着你有:,你应该有::
  • 如果更新服务器不是该开发人员的选项怎么办?当然,这是最好的解决方案,但并不总是可行的选择。
  • @tereško - 我们没有对当前服务器的物理访问权限,因为它由另一家公司托管。他们对这类事情非常敏感。我们正在使用我们自己的服务器迁移到不同的主机

标签: php singleton php-5.2


【解决方案1】:

意想不到的T_PAAMAYIM_NEKUDOTAYIM是这一行中的双冒号(::):

print_r($load::$db->query('SELECT * FROM `users`'));

一个单例类应该能够创建一个且只有一个实例,该实例必须随时可用。实例应该保存数据,但是您使用了静态属性。您应该删除静态属性(或完全避免创建实例)。

所以,如果你想保持这个静态,直接用类名访问:

print_r(controller::$db->query('SELECT * FROM `users`'));

或者,如果您删除静态:

class controller {

    // Store the single instance of controller
    private static $_controller = null;
    public $user;
    public $db;
    public $page;
    public $code;

    // construct the class and set up the user & db instances
    private function __construct() {
        $this->db = new db(HOST, USER, PASS, DB);
        $this->user = new user();
        $this->page = new page();
        $this->code = new code();
    }

    ...// the rest as it is

并在调用时这样做:

$load = controller::getInstance();
print_r($load->db->query('SELECT * FROM `users`'));

【讨论】:

  • 此解决方案有效。谢谢!
【解决方案2】:

“从 PHP 5.3.0 开始,可以使用变量引用类”。

PHP 5.2,这样操作:

class A {
    public $db;
    public static $static_db;
}

// OK
$a = new A();
$a->db;

// ERROR
$a::$static_db;

// OK
A::$static_db;

【讨论】:

    【解决方案3】:

    这里的问题是您正在创建一个类的实例来访问静态变量。

    在这种情况下访问静态变量的正确方法是使用类名和作用域解析运算符"T_PAAMAYIM_NEKUDOTAYIM" 像这样

    Controller::$user; 
    Controller::$db; 
    

    等等。

    话虽如此,您需要做的就是制作一些静态属性,例如@GeorgeMarquest 建议的,否则拥有一个类的唯一静态实例(单例)和一堆静​​态变量是没有用的因为无需构造对象即可访问它们,see

    查看以下站点以更好地了解Singleton Design Pattern 并查看实际的PHP example

    您可能值得看看下面的帖子Why global variables are bad 并评估您是否需要单例。

    【讨论】:

    • 感谢 Onema 提供的额外信息,这个项目只能由少数人在内部访问。会读这个:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2021-11-26
    • 1970-01-01
    • 2023-04-10
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多