如何在静态类中模拟__destruct()?

时间:2011-08-08 15:24:30

标签: php design-patterns static class-design

我为自己的框架编写了一个简单的配置类。

有一些简单的功能,例如get()set()loadFile()。 但是所有函数和变量都是静态的。

现在我想实现自动保存机制。我有想法创建一个实例(在我的init()函数中)__destruct()将调用静态destruct()函数:

<?php

class Config
{
  static private $autoSave;
  static public function get() {} /* set(), save(), load(), etc. */

  static public function init($autoSave)
  {
    self::$autoSave = $autoSave;
    new Config();
  }
  static public function destruct()
  {
    if (self::$autoSave)
      self::save();
  }

  public function __destruct()
  {
    Config::destruct();
  }
}

?>

在这种情况下,有没有更好的解决方案或我的设计模式完全错误?

4 个答案:

答案 0 :(得分:10)

  

在这种情况下,有没有更好的解决方案或我的设计模式完全错误?

仅在对象上调用析构函数,而不是对静态类调用。

相反,您可以将您的类从静态转换为常规,以便您可以创建它的实例。然后它将有析构函数。此外,它使您的代码更易于重复使用和测试。

此外,您还可以为__get__setArrayAccess实施魔术方法,这对于轻松进行数据存储和访问非常有用。

或者,您可以将析构函数对象添加到静态类成员中以实现您正在寻找的内容:

class ConfigDestructor
{
  public function __destruct()
  {
    Config::destruct();
  }
}

class Config
{
  static private $destructorInstance;
  static private $autoSave;
  static public function get() {} /* set(), save(), load(), etc. */

  static public function init($autoSave)
  {
    if (null === self::$destructorInstance) 
        self::$destructorInstance = new ConfigDestructor();

    self::$autoSave = $autoSave;
  }
  static public function destruct()
  {
    if (self::$autoSave)
      self::save();
  }
}

仅供参考:您写道要添加自动保存功能。 __destruct()register_shutdown_function都有一个共同的缺口:

  

注意:脚本的工作目录可以在某些Web服务器下的关闭功能内部进行更改,例如:的Apache。

您应指定一个绝对路径来访问要保存的文件。另见:PHP file creation/write within destructor

答案 1 :(得分:6)

init方法中,添加对register_shutdown_function的调用:

register_shutdown_function(array('Config', 'destruct'));

答案 2 :(得分:3)

你看过register_shutdown_function了吗?您可以将方法添加到脚本的关闭部分。

查看Singleton pattern

也是值得的

答案 3 :(得分:1)

您可以在autoregister上创建此静态类的实例。

$instance = array();
spl_autoload_register(function ($class)
{
    ...
    global $instance;
    if ($isStatic) $instance[] = new $class();
    ...
});

这对我来说很好。

...对于那些不喜欢可读代码的人(未经测试):

class staticInstances()
{
    private static $list = array();

    public static function add($class)
    {
        self::$list[] = new $class();
    }

    function __distruct()
    {
        foreach (self::$list as $class)
            unset(self::$list);
    }
}
$staticInstances = new staticInstances();

spl_autoload_register(function ($class)
{
    ...
    if ($isStatic) staticInstances::add($class);
    ...
});