0

老实说,我认为我在创建尽可能详尽的标题方面做得非常出色:D

我有一个Db扩展类MySQLi。在执行查询之前我有一些事情要做,但是要执行查询我需要调用parent::query(). 问题是那Db是单例,我真的不知道该怎么做..

$result = parent::query($sql);

__construct如果是公开的,这就是有效的。一旦我将其设为私有,我就会开始收到一堆错误,基本上是在说

无法获取数据库

在绝望的尝试中,我尝试了这个,但没有奏效

$result = self::$instance::parent::query($sql)

有人可以告诉我我该怎么做吗?

4

1 回答 1

2

您在标题方面做得很好,但是我对“我有一个Db扩展的课程MySQLi感到窒息。我已经详细解释了为什么这是一个糟糕的主意,所以请不要这样做,那么您就不必担心这个问题了。

更令人不安的是,您正试图从非单身父母中创建一个单身孩子。这确实需要一个私有(或至少受保护的)构造函数,但由于父构造函数是公共的,因此您不能拥有使用更严格的访问修饰符的覆盖构造函数。这是违反合同的行为,违反了所有规则/惯例和广泛接受的“良好”做法

请阅读SOLID 原则

您的代码段的另一个问题是模棱两可:

self::$instance::parent::query($sql);

现在,在子类中,它可能看起来合乎逻辑,并且parent关键字的有效使用,但让我们添加这一行:

self::$instance = new OtherClass();
self::$instance::parent::query($sql);

在这种情况下,可能是一个类常量(它们只是按照惯例parent大写,这不是必需的!)。PHP不是强类型的,你不能假设给定的变量总是相同的类型,现在可以吗?

如果您希望该query方法在子类上随时可用,那么请不要覆盖它:

$evil = Db::getInstance($constructor_args);
$evil->query();//defaults to parent::query, if it's not overriden in the child class.

顺便说一句:

你不应该在 PHP 中使用单例

不,真的,诚实和真实。不。再说一次,我在这件事上也很冗长。请在那里阅读我的答案。它解释了为什么你不应该使用单例。
此外,在你的情况下,由于我对 PHP 中的单例模式的强烈厌恶,我只需创建自己的 PDO 或 MySQLi 实例,从而绕过你的单例子类,并着手让我的生活更轻松,我的无论如何,代码更具可测试性。停止你正在做的事情:这是浪费时间!

单例只是 PHP 中拖累的全局变量,因为它们(根据语言的本质)无法在请求之间保持状态。如果您不想要 2 个实例,请不要首先创建第二个实例。

单身人士和同性婚姻有一些共同点,以一种奇怪的方式:
如果你不喜欢同性婚姻,那是你的问题,而不是他们的问题。你怎么能避免他们的结婚影响你?两种选择:

  • 禁止他们结婚(绝对、命令式、独裁式)
  • 不要嫁给一个同性恋者(个人责任,生活和让生活,灵活的风格)

同样适用于单例:如果您不希望有超过 1 个与数据库的连接,则有 2 个选项:

  • 创建一个单例(绝对、命令式、独裁风格)
  • 不要第二次连接数据库(个人责任,灵活)

这两个选项中哪一个看起来最合理?


注意:如果我上面的类比冒犯了任何人:那不是我的意图,我只是试图说明一点。
顺便说一句(并且偏离主题):如果您认为这两个问题的首选方法在两种情况下都不相同,请随意认为,这是您的特权,但请自行保留,也。:)

于 2013-10-24T11:22:25.953 回答