Инициализатор статического класса в PHP
у меня есть вспомогательный класс с некоторыми статическими функциями. Все функции в классе требуется "тяжелая" функция инициализации один раз (как если бы это был конструктор).
есть хорошая практика для достижения этого?
единственное, о чем я подумал, это позвонить init
функция и прерывание ее потока, если он уже запущен один раз (используя статический $initialized
var). Проблема в том, что мне нужно вызвать его на каждую из функций класса.
6 ответов:
похоже, что вам будет лучше служить синглтон, а не куча статических методов
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__')
. Если это так, он вызывает этот метод. Быстро, просто и эффективно...
Если вам не нравится
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'); ?>
есть способ вызвать
init()
метод один раз и запретить его использование, вы можете превратить функцию в частный инициализатор и ivoke его после объявления класса следующим образом:class Example { private function init() { // do whatever needed for class initialization } } (function () { static::init(); })->bindTo(null, Example::class)();
Примечание - RFC, предлагающий это, все еще находится в состоянии проекта.
class Singleton { private static function __static() { //... } //... }
предлагается для PHP 7.x (см. https://wiki.php.net/rfc/static_class_constructor)