Как создать переменную записи, полученную из функции в классе? - PullRequest
0 голосов
/ 09 февраля 2019

Я пытаюсь добавить запись в свой проект, и я получаю регистраторы, используя поиск в реестре (например, с $logger = LoggerRegistry::get('general');).Мне интересно, как разумно генерировать и хранить такую ​​переменную внутри класса.

В идеале я бы хотел, чтобы каждый класс содержал переменную $ logger (в идеале static и final / const), которая установлена ​​в одной строкеоно объявлено, но я получаю фатальную ошибку «Константа в выражении содержит недопустимые операции».

class Foo
{
    $logger = LoggerRegistry::get('general'); /* Fatal error: Constant expression contains invalid operations */

    public function bar()
    {
        doThing();
        self::$logger->log('');
    }
}

Этот метод выдает «Константа в выражении содержит недопустимые операции».Я понимаю, что это потому, что я пытаюсь установить статическое значение, равное функции, которую нельзя определить во время компиляции.Но к тому времени, когда класс используется или даже упоминается, значение уже установлено.

Есть ли хороший обходной путь к проблеме?Как на практике ведется ведение журналов в PHP?

В идеале я не хочу отказываться от реестра, так как считаю, что он слишком тесно связывает журналирование и классы с использованием журналирования, но при этом возникает проблема с введением функции, вызывающей возникновение проблем.к фатальной проблеме.Кажется чрезмерным иметь новую ссылку для каждого экземпляра.И включение функции __init__() или аналогичной, которая вызывается сразу после объявления класса, кажется немного ненужной.Но я могу добавить это так, что мое автозагрузка автоматически вызывает любую функцию __init__, которую может иметь класс, если она есть.

1 Ответ

0 голосов
/ 11 февраля 2019

Статическое свойство не может быть установлено равным объекту, как объявлено.Он ограничен теми же правилами , что и значения const;его можно установить равным только очень простым выражениям и значениям.Вместо этого, чтобы установить статическое свойство как объект, оно должно быть установлено впоследствии.

Установка его сразу после этого

Установка переменной сразу после определения класса, вне класса, работает отлично (я считаю), как показано, давая статическому свойству изначально нулевое значение.

Foo::$logger = LoggerRegistry::get('general');

class Foo
{
    static $logger;

    public function bar()
    {
        doThing();
        self::$logger->log('');
    }
}

Вы могли бы эквивалентно иметь статический метод (например, _static_init) и немедленно вызывать его, что бы инициализировать такие статические переменные.

Использование автозагрузчика

Альтернативой является добавление в автозагрузчик проверки для некоторого статического атрибута класса файла при загрузке файла с именем, соответствующим классу.Например, при загрузке файла Foo.php, содержащего класс Foo, автозагрузчик может проверить наличие статического свойства (например, одного по имени logger) и установить его (Foo::$logger = ...), или может проверить метод статической инициализации и вызвать его(Foo::static_init()).

Например, это можно сделать следующим образом.

$logger = LoggerRegistry::get('general');

spl_autoload_register( function( $class_name ) use ($logger)
{
    $class_path = BASE_PATH . '/' . str_replace('\\', '/', $class_name) . '.php';
    if ( file_exists($class_path) )
    {
        include $class_path;

        if ( property_exists($class_name, 'logger') )
            $class_name::$logger = $logger;
    }
} );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...