我有一些静态功能的辅助类。 在类的所有功能,需要一个“重”初始化函数运行一次(就好像它是一个构造函数)。
是否有实现这一好的做法?
我想的唯一的事情是调用一个init
函数,并断其流,如果它已经运行一次(使用静态$initialized
变量)。 问题是,我需要调用它的类的功能,每一个。
我有一些静态功能的辅助类。 在类的所有功能,需要一个“重”初始化函数运行一次(就好像它是一个构造函数)。
是否有实现这一好的做法?
我想的唯一的事情是调用一个init
函数,并断其流,如果它已经运行一次(使用静态$initialized
变量)。 问题是,我需要调用它的类的功能,每一个。
听起来像是你想通过一个单独而不是一堆静态方法得到更好的服务
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();
// file Foo.php
class Foo
{
static function init() { /* ... */ }
}
Foo::init();
这样一来,当包含类文件的初始化发生。 您可以确保这只是发生在必要的时候(而且只有一次),通过使用自动加载。
其实,我使用了一个公共静态方法__init__()
我需要初始化(或者至少需要执行一些代码)静态类。 然后,在我的自动加载,在加载一个类会检查is_callable($class, '__init__')
如果是,则调用这个方法。 快速,简单和有效的...
有一种方法调用init()
一次法,禁止它的使用情况,您可以关闭该功能为民营初始化函数和类声明类似这样的后ivoke它:
class Example {
private static function init() {
// do whatever needed for class initialization
}
}
(static function () {
static::init();
})->bindTo(null, Example::class)();
如果你不喜欢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');
?>
注意: 这是什么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接受的答案,我总结了一些人根本就不知道了明显的“幼稚”,办法的(我在这里展示)。 明白了这一点作为一个起点。
注 - RFC提出这个仍处于草案状态。
class Singleton
{
private static function __static()
{
//...
}
//...
}
提出了PHP 7.x版(见https://wiki.php.net/rfc/static_class_constructor )