use*_*626 84 php static constructor class initializer
我有一个带有一些静态函数的辅助类.该类中的所有函数都需要一个"重"初始化函数才能运行一次(就好像它是一个构造函数).
实现这一目标是否有良好的做法?
我唯一想到的是调用一个init函数,并且如果它已经运行一次(使用静态$initializedvar)则会中断它的流程.问题是我需要在每个类的函数上调用它.
Pet*_*ley 112
听起来你更喜欢单身而不是一堆静态方法
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在使用中
// As opposed to this
Singleton::someMethod1();
// You'd do this
Singleton::getInstance()->someMethod1();
Run Code Online (Sandbox Code Playgroud)
Vic*_*let 93
// file Foo.php
class Foo
{
static function init() { /* ... */ }
}
Foo::init();
Run Code Online (Sandbox Code Playgroud)
这样,在包含类文件时就会发生初始化.您可以确保仅在必要时(并且仅使用一次)使用自动加载.
irc*_*ell 55
实际上,我__init__()在需要初始化的静态类上使用公共静态方法(或者至少需要执行一些代码).然后,在我的自动加载器中,当它加载一个类时它会检查is_callable($class, '__init__').如果是,则调用该方法.快速,简单,有效......
注意:这正是 OP 所说的。(但没有显示代码。)我在这里显示了详细信息,以便您可以将其与接受的答案进行比较。我的观点是 OP 的本能是,恕我直言,比他接受的答案要好。
鉴于已接受的答案的投票率如此之高,我想指出静态方法一次性初始化的“天真”答案,几乎没有比单例的实现更多的代码 - 并且具有本质优势。
final class MyClass {
public static function someMethod1() {
MyClass::init();
// whatever
}
public static function someMethod2() {
MyClass::init();
// whatever
}
private static $didInit = false;
private static function init() {
if (!self::$didInit) {
self::$didInit = true;
// one-time init code.
}
}
// private, so can't create an instance.
private function __construct() {
// Nothing to do - there are no instances.
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是您可以使用简单的静态函数语法进行调用:
MyClass::someMethod1();
Run Code Online (Sandbox Code Playgroud)
将其与接受的答案所需的调用进行对比:
MyClass::getInstance->someMethod1();
Run Code Online (Sandbox Code Playgroud)
作为一般原则,最好在对类进行编码时支付一次编码费用,以使调用者更简单。
如果您不使用 PHP 7.4 opcode.cache,请使用Victor Nicollet 的回答。简单的。不需要额外的编码。没有要理解的“高级”编码。(我建议包括 FrancescoMM 的评论,以确保“init”永远不会执行两次。)请参阅Szczepan 关于为什么 Victor 的技术不适用于opcode.cache.
如果ARE使用opcode.cache,那么据我所知我的回答是那样干净,你可以得到。成本只是MyClass::init();在每个公共方法的开头添加一行。注意:如果您想要公共属性,请将它们编码为get/set对方法,以便您有地方添加该init调用。
(私有成员不需要那个init调用,因为它们不能从外部访问——所以在执行到达私有成员时,已经调用了一些公共方法。)
有一种方法可以调用init()一次该方法并禁止其使用,您可以将函数转换为私有初始化程序并在类声明后调用它,如下所示:
class Example {
private static function init() {
// do whatever needed for class initialization
}
}
(static function () {
static::init();
})->bindTo(null, Example::class)();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
93113 次 |
| 最近记录: |