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

发布于 2024-11-28 05:58:22 字数 687 浏览 0 评论 0原文

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

有一些简单的函数,例如 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();
  }
}

?>

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔戏命师 2024-12-05 05:58:22

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

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

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

此外,您还可以为 __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 文件

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.

素衣风尘叹 2024-12-05 05:58:22

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

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

Inside your init method, add a call to register_shutdown_function:

register_shutdown_function(array('Config', 'destruct'));
青衫负雪 2024-12-05 05:58:22

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

查看单例模式也可能是值得的。

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.

断爱 2024-12-05 05:58:22

您可以在自动注册时创建此静态类的实例。

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

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);
    ...
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文