I hope I can explain my problem/questions clearly. Thanks in advance:

------------
Scenario:
I'm working on a Log class that my app will use to write
debug/error/etc messages to a file.  I've created it so that as the
application logs messages, these messages are queued within a property
of the Log class, and only written to the file when the Log object is
being destroyed.

I wanted to place all of the file writing to within __destruct() to
avoid holding a connection to the log file throughout the life of the
app's state.

------------
Problem:
Everything works fine, UNLESS I move the fopen('log-file-name') call
to within the __destruct() method.  If I open a handle to the log file
within the __construct() method, or any other class method, it works
fine.  But I receive a permissions error if it's called within
__destruct().

Error reads: "Warning: fopen(20060331.txt) [function.fopen]: failed to
open stream: Permission denied in ......."

------------
Caveat:
I have found that if I explicitly destroy an instance of Log with
unset(), then fopen() will work even when it is within the
__destruct() method.  However I don't like that solution...and
besides, I'm planning on creating an instance of the Log class from
within the __construct() of my Controller class, and trying to
explicitly destroy Log with an implicit __destruct() of my Controller
doesn't work either. :P

------------
Question(s):
1. Could anyone explain a bit more as to why fopen() won't work within
an implicit call to __destruct()?  What permissions has my app lost at
this point?
2.  Am I at least correct in my intention to limit the duration that
the handle to the log file is open?
3. Is there workaround to this little conundrum that anyone can think of?

------------
Code:
Here's a simplified version of the code (it's complete, feel free to
copy-and-paste-and-play).  I've commented the fopen code block in
question.

[code]
        // Create an instance of Log
        $log = new Log();
        // Attempt to log a message
        Log::debug("Here is a debug message.");

        class Log
        {
                protected static $handle;
                protected static $location;
                protected static $message;

                public function __construct()
                {
                        self::$location = date("Ymd").".txt";
/* Begin fopen() */
/* When placed here, it works */
                        if (!self::$handle = fopen(self::$location,"a"))
                        {
                                echo "Error. Please check permissions.";
                                die;
                        }
/* End fopen() */
                }
                
                public static function debug($message)
                {
                        $timestamp = date("Y-m-d H:i:s T");
                        self::$message .= $timestamp."\tdebug\t".$message."\n";
                }
                
                public function __destruct()
                {
                        if(self::$message)
                        {
/* Begin fopen() */
/* If it's here, it won't work!
                                if (!self::$handle = fopen(self::$location,"a"))
                                {
                                        echo "There was an error attempting to 
open the log file. Please
check permissions.";
                                        die;
                                }
/* End fopen() */
                                if (fwrite(self::$handle, self::$message) === 
FALSE)
                                {
                                        echo "Cannot write to file 
({$this->location})";
                                        exit;
                                }
                                @fclose(self::$handle);
                        }
                }
        }

[/code]

-John W

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to