开发者

How to emulate __destruct() in a static class?

I've coded a simple configuration class for my own framework.

There are simple functions like get(), set() or loadFile(). But all functions and variables are static.

And now I want to implement an autosave mechanism. I had the idea to create an instance (in my init() function) whose __destruct() will call the static destruct() function:

<?php

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

  static public funct开发者_C百科ion init($autoSave)
  {
    self::$autoSave = $autoSave;
    new Config();
  }
  static public function destruct()
  {
    if (self::$autoSave)
      self::save();
  }

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

?>

Are there any better solutions or is my design pattern completely wrong in this case?


Are there any better solutions or is my design pattern completely wrong in this case?

Destructors are called on objects only, not for static classes.

Instead you could convert your class from static to regular so you can create an instance of it. Then it will have the destructor. Additionally it makes your code easier to re-use and test.

Additionally you're able to implement magic methods for __get and __set or ArrayAccess which often is useful for easy data storage and access as for a configuration.

Alternatively, you can add a destructor object to a static class member to achieve what you're looking for:

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();
  }
}

Just FYI: You wrote you want to add an auto-save functionality. There is a common gap to fall over for both __destruct() and register_shutdown_function:

Note: Working directory of the script can change inside the shutdown function under some web servers, e.g. Apache.

You should specify an absolute path to access the file you want to save into. See as well: PHP file creation/write within destructor.


Inside your init method, add a call to register_shutdown_function:

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


Have you looked at register_shutdown_function? You could add your method to the shutdown part of the script.

It could also be worth it to look at the Singleton pattern.


You can create an instance of this static class on autoregister.

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

This is working fine for me.

... and for those who don't like readable code (it is untested):

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);
    ...
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜