PHP:如何防止扩展类的多个实例

Posted

技术标签:

【中文标题】PHP:如何防止扩展类的多个实例【英文标题】:PHP: How to prevent multiple instances of extended class 【发布时间】:2017-05-08 04:40:59 【问题描述】:

我有一个包含全局使用方法的类,并通过扩展类来使用它们:

App.php

final class App extends Core 

  // The app class handles routing and basically runs the show


Core.php

abstract class Core 

  public function __construct()  // Here we bring in other classes we use throughout the app
    $this->Db = new Db($this);
    $this->Mail = new Mail($this);
  

  // Then we define multiple methods used throughout the app

  public function settings($type) 
    // You see this used by the model below
  


index.php

$App = new App(); // This fires up the app and allows us to use everything in Core.php

到目前为止,这一切都很好,因为整个站点的所有内容都在 $App 内处理。但是,在我的 MVC 结构中,模型需要从数据库中提取数据,以及检索所有包含在 Core 中的其他设置。我们不需要模型使用整个$App 类,但我们需要Core

MyModel.php

class MyModel extends Core  

  public function welcome() 
    return 'Welcome to '.$this->settings('site_name');
  


一旦MyModel.php 起作用,Core 构造函数就会第二次运行。如何防止Core 构造函数运行两次?

【问题讨论】:

这篇文章可能会有所帮助:***.com/questions/23160509/… 你的 App 类不应该访问 db.. 只有模型应该这样做.. 另外,看看并阅读依赖注入:***.com/questions/130794/what-is-dependency-injection 作为一个不能有多个实例的App类,你可以使用Singleton模式(这只是一个提示,小心Singleton模式,“强大的力量来自巨大的责任”)。 App 类不应访问存储。可以使用很多模式,Register 模式、Service Provider(即 Register)或 Connection Manager 可以管理您的服务实例。依赖注入(如前所述)是共享依赖的最佳方式,无需在没有控制的情况下创建。 【参考方案1】:

您可以在core 类中使用静态实例并重用它。

abstract class Core 
  public static $instance; //create a static instance

  public function __construct()  // Here we bring in other classes we use throughout the app
    $this->Db = new Db($this);
    $this->Mail = new Mail($this);
    self::$instance = $this; // initialise the instance on load
  

  // Then we define multiple methods used throughout the app

  public function settings($type) 
    // You see this used by the model below
  


在模型类中,这样使用

class MyModel extends Core  

  public function welcome() 
    $_core = Core::instance; // get the present working instance
    return 'Welcome to '.$_core->settings('site_name');
  


你可以看看这个singleton reference 另外你可以检查这个答案explain-ci-get-instance

【讨论】:

您的代码有一些问题。首先,它不是单例,因为我们可以实例化任意数量的类。其次,使用构造来创建和存储他自己的实例是一种不好的做法,因为这不是它的目的。第三,您需要测试它是否有实例或是否需要实例化。最后,CI 的程序设计非常糟糕,因为您链接了一个非常糟糕的编码类。

以上是关于PHP:如何防止扩展类的多个实例的主要内容,如果未能解决你的问题,请参考以下文章

如何防止在 PHP 中重复提交表单(跨多个窗口进行保护)?

在单个 AppDomain 上运行多个应用程序实例时如何防止属性覆盖?

PHP在单例模式中,是多个线程只有一个实例还是一个线程只有一个实例

php实例化多个类

Symfony2

如何防止 start-stop-daemon 在 cronjob 中创建多个实例?