Hallo,
zu logging Zwecken habe ich in meinem aktuellen Projekt eine Log Klasse implementiert:
das passt auch soweit alles. Problem ist nur das zu Ende des Skriptes der Destruktor aufgerufen wird, das eigentliche Objekt aber immer noch im Speicher vorhanden zu sein scheint. Siehe an folgender Ausgabe:
Der GC räumt also nach und nach den Speicher auf und "löscht" das Objekt der Vp_Log Klasse, der Destruktor wird aufgerufen und das FileHandle wird geschlossen. Die Objekte der anderen Klassen werden auch gelöscht und deren Destruktoren werden aufgerufen, in diesen wird jeweils ein Logeintrag gemacht, was nicht funktioniert, da der Destruktor der Vp_Log Klasse schon aufgerufen wurde.
Das seltsame daran ist, dass die statische Variable $instance aus der Vp_Log Klasse eben nicht leer ist nachdem der Destruktor aufgerufen wurde.
Jemand eine Idee wieso das so ist?
zu logging Zwecken habe ich in meinem aktuellen Projekt eine Log Klasse implementiert:
PHP-Code:
<?php
class Vp_Log {
private static $instance;
private $startTime;
private $fileHandle = null;
private $logLevel;
public static function getInstance() {
var_dump(self::$instance);
if (self::$instance === null) {
self::$instance = new self;
self::$instance->Init(5);
}
return self::$instance;
}
private function __construct() { }
private function __clone() { }
public function Init($logLevel) {
$this->setLogLevel($logLevel);
if ($this->getLogLevel() > 0) {
$this->startTime = microtime(true);
$this->setFileHandle(fopen(BASE_PATH . '/' . 'log', 'ab'));
if ($this->getFileHandle() == false) {
throw new Vp_Exception('Couldn´t open logfile');
}
$strToFile = date('d-m-Y_H:i:s') . ' site request from ip ' . $_SERVER['REMOTE_ADDR'] . "\n";
fwrite($this->getFileHandle(), $strToFile);
}
}
public function __destruct() {
if ($this->getLogLevel() > 0) {
$neededTime = microtime(true) - $this->getStartTime();
$strToFile = date('d-m-Y_H:i:s') . ' needed ' . $neededTime . ' seconds for execution' . "\n";
fwrite($this->getFileHandle(), $strToFile);
fclose($this->getFileHandle());
}
echo 'Destroying Vp_Log' . "\n";
}
public function setStartTime($time) {
$this->startTime = $time;
}
public function getStartTime() {
return $this->startTime;
}
public function setFileHandle($fileHandle) {
$this->fileHandle = $fileHandle;
}
public function getFileHandle() {
return $this->fileHandle;
}
public function setLogLevel($level) {
$this->logLevel = $level;
}
public function getLogLevel() {
return $this->logLevel;
}
public function write($message, $level) {
if ($level <= $this->getLogLevel()) {
fwrite($this->getFileHandle(), date('d-m-Y_H:i:s') . ' ' . $message . "\n");
}
}
public static function w($message, $level) {
self::getInstance()->write($message, $level);
}
}
Code:
NULL object(Vp_Log)#1 (3) { ["startTime":"Vp_Log":private]=> float(1271229645.0748) ["fileHandle":"Vp_Log":private]=> resource(4) of type (stream) ["logLevel":"Vp_Log":private]=> int(5) } --- weitere Aufrufe der Logklasse und danach der HTML-Code der Seite --- Destroying Vp_Log // ab jetzt sollte Vp_Log::$instance wieder null sein, ist aber nicht der Fall object(Vp_Log)#1 (3) { ["startTime":"Vp_Log":private]=> float(1271229645.0748) ["fileHandle":"Vp_Log":private]=> resource(4) of type (Unknown) ["logLevel":"Vp_Log":private]=> int(5) } Warning: fwrite(): 4 is not a valid stream resource in C:\workspace\web\netboot\abc\Vp\Log.php on line 70
Das seltsame daran ist, dass die statische Variable $instance aus der Vp_Log Klasse eben nicht leer ist nachdem der Destruktor aufgerufen wurde.
Jemand eine Idee wieso das so ist?
Kommentar