【问题标题】:Strict standards warning: Singleton implementation with PHP严格标准警告:使用 PHP 实现单例
【发布时间】:2013-01-24 04:27:03
【问题描述】:

我使用 Zend 框架为我的 PHP 应用程序创建了一个单例记录器。

实现非常简单:

class Logger
{
    protected static $_logger;

    private function __construct()
    {
        // initialize logger
        $writer = new Zend_Log_Writer_Stream(LOG_PATH);
        $this->_logger = new Zend_Log($writer);
    }

    public static function getLogger()
    {
        if (null === self::$_logger)
        {
            self::$_logger = new self();
        }        
        return self::$_logger;
    }

    public static function Log($message, $logType)
    {
        if ($logType <= LOG_MAX)
        {
            $logger = self::getLogger();        
            $logger->_logger->log($message, $logType);
        }
    }
}

要在日志中添加一个条目,我只需调用静态方法: Logger::Log('message', Zend_Log::ERR);

Logger 按预期工作,但由于我已将我的 PHP 版本升级到 5.4.3,我收到一个错误:

严格标准:在第 28 行的 Z:\Software\PHP\EA Game\application\classes\Logger.php 中将静态属性 Logger::$_logger 作为非静态访问

第 28 行在函数 __construct(): $this-&gt;_logger = new Zend_Log($writer);

我总是可以禁用E_STRICT,但这不是一个更好的选择。 我想在没有收到严格标准警告的情况下实现单例模式。

如果有人能指出正确的方向来实现单例模式而不收到字符串标准警告,我将不胜感激。

编辑: 我使用了 jValdrons 的建议并将 $this->_logger 替换为 self::$_logger。 我仍然收到严格的标准警告,我将 Log 函数更改为如下:

public static function Log($message, $logType)
{
    if ($logType <= LOG_MAX)
    {
        self::getLogger()->log($message, $logType);
    }
}

但现在我有另一个问题。

代码不会抛出严格标准警告,但它不能按预期工作。

我有 2 个单独的记录器,1 个用于应用程序,1 个用于 crons。 基本上它只是相同的代码: 2个静态变量:

protected static $_logger;
protected static $_cronLogger;

构造函数初始化它们:

private function __construct()
{
    // initialize all loggers
    $writer = new Zend_Log_Writer_Stream(LOG_PATH);
    self::$_logger = new Zend_Log($writer);

    $writerCron = new Zend_Log_Writer_Stream(CRON_LOG_PATH);
    self::$_cronLogger = new Zend_Log($writerCron);
}

还有2个方法GetCronLogger()和LogCron():

public static function getCronLogger()
{
if (null === self::$_cronLogger)
    {
    self::$_cronLogger = new self();
}        
return self::$_cronLogger;
}


public static function LogCron($message, $logType)
{
    if ($logType <= CRON_LOG_MAX)
    {
        self::getCronLogger()->log($message, $logType);
    }
}

但是现在 self::getCronLogger()->log($message, $logType);调用我的方法 Log(),而不是 Zend_log->log(),它总是将记录添加到我的主记录器,而不是 crons 记录器。

我是否遗漏了某些东西或以不正确的方式调用了某些东西?

【问题讨论】:

  • 这不是单例..这是静态方法!
  • 是的,它们是静态方法。但是他们使用的是单例模式——静态变量 $_logger 是 Zend_Log() 类的一个实例,它只会被初始化一次。所有后续请求都将使用相同的实例,该实例位于 $_logger 变量中。

标签: php singleton standards strict


【解决方案1】:

您正在使用 $this->logger 访问记录器,这不是访问它的静态方式。因为它是一个静态变量,所以你必须使用 self:: 就像你使用 getLogger 一样,所以:

private function __construct()
{
    // initialize logger
    $writer = new Zend_Log_Writer_Stream(LOG_PATH);
    self::$_logger = new Zend_Log($writer);
}

【讨论】:

  • 谢谢!这加上 Log 函数的变化起到了作用。公共静态函数 Log($message, $logType) { self::getLogger(); self::$_logger->log($message, $logType); }
  • 但现在它不像预期的那样工作了......我编辑了我的第一篇文章并添加了更多解释。
猜你喜欢
  • 1970-01-01
  • 2012-03-12
  • 2013-02-09
  • 2015-03-15
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
相关资源
最近更新 更多