Как эмулировать __destruct () в статическом классе? - PullRequest
6 голосов
/ 08 августа 2011

Я кодировал простой класс конфигурации для моей собственной инфраструктуры.

Существуют простые функции, такие как 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 ]

10 голосов
/ 08 августа 2011

Есть ли лучшие решения или мой шаблон дизайна в этом случае совершенно неверен?

Деструкторы вызываются только для объектов, но не для статических классов.

Вместо этого вы можете преобразовать свой класс из статического в обычный, чтобы создать его экземпляр. Тогда у него будет деструктор. Кроме того, он упрощает повторное использование и тестирование вашего кода.

Кроме того, вы можете реализовать магические методы для __get и __set или ArrayAccess, что часто полезно для простого хранения данных и доступа к ним, как для конфигурации.

Кроме того, вы можете добавить объект-деструктор к члену статического класса, чтобы достичь того, что вы ищете:

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:

Примечание: Рабочий каталог скрипта может изменяться внутри функции выключения на некоторых веб-серверах, например Apache.

Вы должны указать абсолютный путь для доступа к файлу, в который вы хотите сохранить. Смотрите также: Создание / запись PHP-файла в деструкторе .

6 голосов
/ 08 августа 2011

Внутри вашего init метода добавьте вызов к register_shutdown_function:

register_shutdown_function(array('Config', 'destruct'));
3 голосов
/ 08 августа 2011

Вы смотрели на register_shutdown_function ? Вы можете добавить свой метод в часть скрипта shutdown.

Также стоит взглянуть на шаблон Singleton .

1 голос
/ 12 октября 2013

Вы можете создать экземпляр этого статического класса при автоматической регистрации.

$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);
    ...
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...