静态类初始化在PHP静态类初始化在PHP(Static class initializer in P

2019-05-13 06:13发布

我有一些静态功能的辅助类。 在类的所有功能,需要一个“重”初始化函数运行一次(就好像它是一个构造函数)。

是否有实现这一好的做法?

我想的唯一的事情是调用一个init函数,并断其流,如果它已经运行一次(使用静态$initialized变量)。 问题是,我需要调用它的类的功能,每一个。

Answer 1:

听起来像是你想通过一个单独而不是一堆静态方法得到更好的服务

class Singleton
{
  /**
   * 
   * @var Singleton
   */
  private static $instance;

  private function __construct()
  {
    // Your "heavy" initialization stuff here
  }

  public static function getInstance()
  {
    if ( is_null( self::$instance ) )
    {
      self::$instance = new self();
    }
    return self::$instance;
  }

  public function someMethod1()
  {
    // whatever
  }

  public function someMethod2()
  {
    // whatever
  }
}

然后,在使用

// As opposed to this
Singleton::someMethod1();

// You'd do this
Singleton::getInstance()->someMethod1();


Answer 2:

// file Foo.php
class Foo
{
  static function init() { /* ... */ }
}

Foo::init();

这样一来,当包含类文件的初始化发生。 您可以确保这只是发生在必要的时候(而且只有一次),通过使用自动加载。



Answer 3:

其实,我使用了一个公共静态方法__init__()我需要初始化(或者至少需要执行一些代码)静态类。 然后,在我的自动加载,在加载一个类会检查is_callable($class, '__init__') 如果是,则调用这个方法。 快速,简单和有效的...



Answer 4:

有一种方法调用init()一次法,禁止它的使用情况,您可以关闭该功能为民营初始化函数和类声明类似这样的后ivoke它:

class Example {
    private static function init() {
        // do whatever needed for class initialization
    }
}
(static function () {
    static::init();
})->bindTo(null, Example::class)();


Answer 5:

如果你不喜欢public静态初始化,反射可以是一个解决办法。

<?php

class LanguageUtility
{
    public static function initializeClass($class)
    {
        try
        {
            // Get a static method named 'initialize'. If not found,
            // ReflectionMethod() will throw a ReflectionException.
            $ref = new \ReflectionMethod($class, 'initialize');

            // The 'initialize' method is probably 'private'.
            // Make it accessible before calling 'invoke'.
            // Note that 'setAccessible' is not available
            // before PHP version 5.3.2.
            $ref->setAccessible(true);

            // Execute the 'initialize' method.
            $ref->invoke(null);
        }   
        catch (Exception $e)
        {
        }
    }
}

class MyClass
{
    private static function initialize()
    {
    }
}

LanguageUtility::initializeClass('MyClass');

?>


Answer 6:

注意: 这是什么OP说他们做到了。 (但并没有显示代码)。我告诉细节,在这里,让你可以把它比作接受的答案。 我的观点是OP的原始本能,恕我直言,不是他接受的答案更好。


考虑到如何高度upvoted接受的答案是,我想指出的静态方法的“天真”的答案一次性初始化,几乎比辛格尔顿,落实更多的代码-并具有核心优势

final class MyClass  {
    public static function someMethod1() {
        MyClass::init();
        // whatever
    }

    public static function someMethod1() {
        MyClass::init();
        // whatever
    }


    private static $didInit = false;

    private static function init() {
        if (!$didInit) {
            $didInit = true;
            // one-time init code.
        }
    }

    // private, so can't create an instance.
    private function __construct() {
        // Nothing to do - there are no instances.
    }
}

这种方法的好处你得到了简单的静态函数语法来调用:

MyClass::someMethod1();

它对比的是接受的答案所需的调用:

MyClass::getInstance->someMethod1();

作为一般原则,最好是支付一次编码的价格,当你编写一个类,让呼叫者简单。


所有的答案(包括本)中,我更喜欢维克多尼科莱特的答案 。 简单。 无需额外的编码。 没有“高级”编码理解。 (我建议包括FrancescoMM的评论,以确保“初始化”将不会执行两次。)

所以我一直懒得写这个答案。 但是,这么多的人upvoted接受的答案,我总结了一些人根本就不知道了明显的“幼稚”,办法的(我在这里展示)。 明白了这一点作为一个起点。



Answer 7:

注 - RFC提出这个仍处于草案状态。


class Singleton
{
    private static function __static()
    {
        //...
    }
    //...
}

提出了PHP 7.x版(见https://wiki.php.net/rfc/static_class_constructor )



文章来源: Static class initializer in PHP