Я возился с разными фреймворками ведения журналов PHP. Я сейчас пробую PEAR :: Log. Я решил, что использую его функцию singleton, чтобы убедиться, что существует только один экземпляр класса.
У меня есть небольшой скрипт, похожий на демона, который я хотел добавить в журнал, потому что это был, вероятно, самый простой скрипт в системе для тестирования. У этого скрипта есть несколько функций. Я, вероятно, захочу регистрировать вещи внутри функций.
У меня вопрос, как мне лучше всего управлять этим синглтоном?
Мне это звонят:
&Log::singleton($handler, $name, $ident, $conf, $maxLevel);
в каждой функции не кажется идеальным, особенно потому, что я уже указал все параметры в первоначальном вызове. Pear :: Log сериализует эту информацию, но, судя по всему, вам все равно нужно предоставить все эти переменные, чтобы получить экземпляр.
Другой альтернативой является передача экземпляра в каждую функцию. Опять же, похоже, что это далеко не идеально.
Я полагаю, вы также можете сделать экземпляр «глобальным».
Что делать в этой ситуации? Есть ли лучшие решения?






Я мало что знаю о PEAR :: Log, но почему бы не создать еще один синглтон, который обертывает / упрощает ведение журнала.
class Logger {
private static $log;
private function __construct() { }
public static function init(Log $log) {
self::$log = $log;
}
public static function get() {
return self::$log;
}
}
После инициализации Logger экземпляром Log вы можете получить к нему доступ через Logger::get. Поскольку в PHP возможно разыменование, вы можете сделать
Logger::get()->doSomething($foo, $bar);
Просто используйте глобальный экземпляр. Где-то у вас должен быть файл, который должны включать все остальные файлы. Просто создайте его там. Если у вас есть что-то против глобальных переменных, вам, вероятно, не следует программировать на PHP.
Если он пишет библиотеку, осторожность - это хорошо. Но для моего собственного небиблиотечного кода я предпочитаю удобочитаемость. $ LOGGER-> foo () намного лучше, чем Logger :: get () -> foo (). В моей версии вы можете отключить регистратор с помощью небольшого класса: class NoLogger {public function __get () {} public function __call () {}};
А еще лучше, если ваша конечная цель - просто вызвать вслепую
Logger::Write("Something happened");
где бы вы ни нуждались, вы можете продвинуть решение Михала на один шаг вперед с
class Logger {
private static $log = null;
public static function init(Log $log) {
self::$log = $log;
}
public static function Write(String $str) {
if ($log == null)
init(Log::singleton(...));
$this->log->Write($str);
}
}
Таким образом, ваш журнал будет инициализирован один раз при первом использовании.
Another alternative is passing the instance into every function. Again, seems like its less than ideal.
В основном у вас есть выбор передачи зависимостей для каждой функции, для каждого экземпляра объекта или в одной из глобальных областей. Я считаю, что использование области экземпляра объекта обычно обеспечивает хороший баланс гибкости. Как правило, вы должны попытаться максимально ограничить область переменных, поэтому, если это имеет смысл, непременно передавайте параметры функции.
Синглтон может быть специфичным для пространства имен (то есть «префиксным классом» до 5.3), что не может быть выполнено с помощью глобальной переменной. Всегда приятно, когда вы включаете библиотеку, которая использует глобальную переменную, без которой она не будет работать ...