使用「;“魔法班”;为了避免PHP致命错误,好主意?
在我的许多网站上,我使用自制的PHP类“Logger”(基本上,它用于将信息记录到日志文件中,并按日期自动组织这些文件:年/月) 我通过在我的引导文件中创建一个Logger实例来使用它(包括在任何地方): 这迫使我在需要记录某些内容的每个函数中设置使用「;“魔法班”;为了避免PHP致命错误,好主意?,php,oop,design-patterns,singleton,magic-methods,Php,Oop,Design Patterns,Singleton,Magic Methods,在我的许多网站上,我使用自制的PHP类“Logger”(基本上,它用于将信息记录到日志文件中,并按日期自动组织这些文件:年/月) 我通过在我的引导文件中创建一个Logger实例来使用它(包括在任何地方): 这迫使我在需要记录某些内容的每个函数中设置$mainLogger全局,并在调用任何方法之前检查记录器是否实例化: function foo($bar){ global $mainLogger; if( !is_null($mainLogger) ){ // If
$mainLogger
全局,并在调用任何方法之前检查记录器是否实例化:
function foo($bar){
global $mainLogger;
if( !is_null($mainLogger) ){
// If the logger is instanciated, I can log my message
$mainLogger->log('error', 'mysql-errors', "My error message lorem ipsum dolor sit amet", Logger::GRAN_MONTH);
}
}
为了使这个工具更易于使用和编写更少的代码,我正在考虑创建一个函数(在Logger类之外),用于处理$mainLogger
(类似于单例设计模式)的实例化和检索:
MagicalClass旨在避免致命错误(致命错误:调用未定义的方法…),例如通过调用它(不包括Logger.class.php)可能引发的致命错误:
多亏了\u call和\u get,任何尝试使用Logger类的属性或方法都不会导致任何错误(错误记录是可选功能,如果Logger不存在,它不应该简单地使应用程序崩溃)
你怎么看这种方法,这是个坏主意吗?
这会给我带来麻烦吗?什么样的麻烦
谢谢
PS:如果你想看Logger类,你可以在我的网站上下载。你在这里描述的“问题”可以通过多种方式解决。最常见的三种是:
工厂级
。工厂类是一个对象生成工厂。工厂本身是一个静态类或单例类,在类中全局使用class Foo
{
public function Bar()
{
$logger = ClassFactory::CreateLogger();
$logger->log('error', 'mysql-errors',
"My error message lorem ipsum dolor sit amet", Logger::GRAN_MONTH);
}
}
依赖注入
class Foo
{
private $logger;
public function __construct($logger)
{
$this->logger = $logger;
}
public function Bar()
{
$this->logger->log('error', 'mysql-errors',
"My error message lorem ipsum dolor sit amet", Logger::GRAN_MONTH);
}
}
你在这里描述的“问题”可以通过多种方式解决。最常见的三种是:
工厂级
。工厂类是一个对象生成工厂。工厂本身是一个静态类或单例类,在类中全局使用class Foo
{
public function Bar()
{
$logger = ClassFactory::CreateLogger();
$logger->log('error', 'mysql-errors',
"My error message lorem ipsum dolor sit amet", Logger::GRAN_MONTH);
}
}
依赖注入
class Foo
{
private $logger;
public function __construct($logger)
{
$this->logger = $logger;
}
public function Bar()
{
$this->logger->log('error', 'mysql-errors',
"My error message lorem ipsum dolor sit amet", Logger::GRAN_MONTH);
}
}
我相信你不需要这门魔法课 首先,这个magic类没有实现
记录器
,因此类型提示(这是一件好事)将不起作用。其次,由于您的magic类没有实现或扩展Logger
,因此任何IDE也不会在magic类上显示自动完成。的确是件坏事
如果以前未加载记录器
,则只需要magic类。这是非常基本的故障,应该很容易检测到。最简单的方法是将记录器
包含在现在具有magic类的文件中
另一方面,如何保证函数getLogger()
可用?如果记录器
可能不可用,则功能可能相同,您的代码也会同样失败
代码改进:不要使用此选项:
function getLogger(){
global $mainLogger;
您不需要全局变量,只需要存储记录器以供以后检索的变量。请改用静态变量:
function getLogger(){
static $mainLogger;
如果您使用它,这个函数可以直接进入工厂类并被静态调用。变量
$mainLogger
将成为类的静态属性,可能在私有范围内。我认为您不需要这个神奇的类
首先,这个magic类没有实现记录器
,因此类型提示(这是一件好事)将不起作用。其次,由于您的magic类没有实现或扩展Logger
,因此任何IDE也不会在magic类上显示自动完成。的确是件坏事
如果以前未加载记录器
,则只需要magic类。这是非常基本的故障,应该很容易检测到。最简单的方法是将记录器
包含在现在具有magic类的文件中
另一方面,如何保证函数getLogger()
可用?如果记录器
可能不可用,则功能可能相同,您的代码也会同样失败
代码改进:不要使用此选项:
function getLogger(){
global $mainLogger;
您不需要全局变量,只需要存储记录器以供以后检索的变量。请改用静态变量:
function getLogger(){
static $mainLogger;
如果您使用它,这个函数可以直接进入工厂类并被静态调用。变量
$mainLogger
将成为类的静态属性,可能在私有范围内。生产代码中不应出现致命错误。致命错误通常是非常严重的运行时错误,或者更糟的是语法错误(语法错误是编译时的,它们不能通过任何编程方式记录,并且总是致命的)。我认为JvdBerg的答案是正确的。使用包含日志功能的公共基类可能是一个快速修复方法?你可以帮助我们