Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 function 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?

like image 914
ComFreek Avatar asked Aug 08 '11 15:08

ComFreek


People also ask

What is static destructor?

Static destructors are executed one by one in reverse order to the order of corresponding classes definition. Static destructors are always executed after software entry point and always after constructors of all global objects.

How do you declare a static variable in a class python?

When we declare a variable inside a class but outside any method, it is called as class or static variable in python. Class or static variable can be referred through a class but not directly through an instance.

Is it impossible to create a static variable in a Python class?

Yes, definitely possible to write static variables and methods in python. Static Variables : Variable declared at class level are called static variable which can be accessed directly using class name.


1 Answers

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.

like image 98
hakre Avatar answered Sep 30 '22 15:09

hakre