views:

126

answers:

3

How is it possible that the snippet below prints out "readablenot readable" ? afaik a die() should stop everything immediately?

EDIT: posted the full function. This is a function from Zend_Search_Lucene_Storage_File_Filesystem. We're always getting "file not readable" errors. The file does seem to be readable but the snippet below prints out "readablenot readable"

EDIT 2: sorry, made some mistakes in the info I posted; all correct now.

public function __construct($filename, $mode='r+b')
    {
        global $php_errormsg;

        if(strpos($mode, 'w') === false) {
            die('not readable');
        }
        else die('readable');

        if (strpos($mode, 'w') === false  &&  !is_readable($filename)) {
            // opening for reading non-readable file
            require_once 'Zend/Search/Lucene/Exception.php';
            throw new Zend_Search_Lucene_Exception('File \'' . $filename . '\' is not readable.');
        }

        $trackErrors = ini_get('track_errors');
        ini_set('track_errors', '1');

        $this->_fileHandle = @fopen($filename, $mode);

        if ($this->_fileHandle === false) {
            ini_set('track_errors', $trackErrors);
            require_once 'Zend/Search/Lucene/Exception.php';
            throw new Zend_Search_Lucene_Exception($php_errormsg);
        }

        ini_set('track_errors', $trackErrors);
    }
+7  A: 

I'm gonna go out on a limb and say:

It's not possible.

Unless: You're echoing 'ok' someplace else before the die() or it's in a destructor/shutdown function.

From the manual on exit() which is the same as die():

Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit() is called.

But the code posted, by itself, would never result in an output of 'okok'.

To Troubleshoot:

  • Change the echoed line to something more traceable. Include the file name (__file__) and line number (__line__) just to make sure it really is the same line being executed.
  • Add a debugger (something like xdebug) to give you a stack trace. Is the function somehow being called twice (by a destructor or shutdown hook)?
Tim Lytle
Agree fully ... yet this still happens :(
stef
@stef: so then maybe you should post the code around the calling of the constructor? Show us how / where you are instantiating this class and we might see the problem.
Narcissus
Added some troubleshooting ideas.
Tim Lytle
actually, shutdown code can still run, so in theory the output is possible, but not by running the die() twice in this function.
StasM
@StasM I knew output was possible, but I figured PHP wouldn't allow the function that called die() to be called again from destructor/shutdown. You're saying that's correct, there won't be any recursive calling?
Tim Lytle
If the user calls the same function from shutdown again, it can happen. PHP doesn't "remember" which function called die() or anything like that. I'm not sure it's smart to call ctors and create objects in shutdown function, but in theory it can happen.
StasM
Tim, __file__ confirms it's coming from the same file, full path is printed out 2X. The __line__ doesn't seem to print anything but a debug_backtrace() at the top refers to the file I'm in (ok), the __construct function (ok) and a line number that contains nothing but { and is not inside the __construct function ... ?
stef
+2  A: 

die() triggers execution of shutdown hooks, so the second call may be part of a code path belonging to a shotdown hook.

hurikhan77
+1  A: 

One answer could be that you have something in your script which caused the offending code to run twice (i.e. a non-terminated http redirect, or your class is being instantiated twice).

Track back from the point (or points) where your class is instantiated and look for possible duplication. Or, setup a unit test / script that does nothing else but instantiate the class once with the minimal amount of data required for the test.

Brian Lacy