_destruct : Quick question

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

marty pain
Forum Contributor
Posts: 105
Joined: Thu Jun 11, 2009 5:32 am
Location: Essex

_destruct : Quick question

Post by marty pain »

If header(location:<url>) is used in a script, are all the classes used prior to this properly destructed, as in the user defined _destruct functions are called if they exist?
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

To my knowledge, yes. If memory serves me correctly, the script finishes execution even after a call to header('location...'), which would imply that classes destruct. I'm curious, I'll give this a test real fast and see what happens.

Yep, testing seems to confirm this:

Code: Select all

<?php
class Test
{
  private $fp;
 
  public function __construct() {
    $this->fp = fopen("/tmp/test.txt","a");
    fputs($this->fp,date("Y-m-d H:i:s") . " construct.\n");
  }
 
  public function __destruct() {
    if( $this->fp )
    {
      fputs($this->fp,date("Y-m-d H:i:s") . " destruct.\n");
      fclose($this->fp);
    }
  }
}
 
$t = new Test();
sleep(3);
header("Location:http://www.google.com");
 

Code: Select all

2009-07-28 09:35:51 construct.
2009-07-28 09:35:54 destruct.
-Andy
marty pain
Forum Contributor
Posts: 105
Joined: Thu Jun 11, 2009 5:32 am
Location: Essex

Re: _destruct : Quick question

Post by marty pain »

Excellent thanks mate.

That does leave me with a problem though as one of my classes isn't destructing properly!
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

I would imagine there are circumstances that would make it destruct improperly. Perhaps things that work on the output buffer... what's your destructor look like?
marty pain
Forum Contributor
Posts: 105
Joined: Thu Jun 11, 2009 5:32 am
Location: Essex

Re: _destruct : Quick question

Post by marty pain »

The PHP $_SESSION is wrapped up in a class so information can be stored in a database, the destructor just calls session_write_close();

Code: Select all

function __destruct() {
            session_write_close();
        }
Bit worried as the same code works on our main server. The only difference is that the server uses PHP 5.2.4 and is running Ubuntu server and my machine uses PHP 5.2.9 and running Fedora 11. I have double checked everything (really everything) in php.ini and all is the same.
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

Check the documentation for session_write_close. It looks like you need to make session call stuff before you make a header call. session stuff hits the output buffer, so this makes sense. It also looks like if everything is functioning normally, you don't typically need to make a call to session_write_close as session data should expire and commit normally unless you have two or more scripts hitting the same session at the same time.

-Andy
marty pain
Forum Contributor
Posts: 105
Joined: Thu Jun 11, 2009 5:32 am
Location: Essex

Re: _destruct : Quick question

Post by marty pain »

Thanks, I'll have a read tomorrow as it's the end of the day.

Any idea why there might be inconsistent behaviour between the two installs/versions?
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

I imagine the difference in behavior is that one is warning silently and the other may not be. it sounds like operationally they're the same. can you confirm if the session is closed from the mysql db on both servers, after the __destruct ?
marty pain
Forum Contributor
Posts: 105
Joined: Thu Jun 11, 2009 5:32 am
Location: Essex

Re: _destruct : Quick question

Post by marty pain »

Both the server and my machine use the same database which is located on the server. I will check the status of the session in the DB tomorrow as i'm off for a well earned drink!

I just had a quick read on php.net via your link and it looks like lots of people have had the same sort of problem as me. I added a die(); on the line after the header, as recommended, and it's fine now, as it officially ends the script, which in turn calls the destructor.

Thanks for the help Andy! Really appreciate it mate!
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

Any time! Have a drink for me, I haven't earned one yet today :)
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

McInfo wrote:I think your test script is a little misleading, andyhoneycutt, because the call to header() appears on the last line of the script. It should not be assumed that header() triggers the destructor.
Oh, my apologies! I didn't mean to imply that header was triggering the destructor, rather that the script finishing execution causes the destructor to trigger.
McInfo wrote:The destructor is not called:

Code: Select all

$c = new C;
sleep(2);
header('Location: ./other.php');
This is essentially the same logic I posted, which does in fact call the descrutor at the end of script execution. I'm wondering why it wouldn't on your setup but does on mine.

-Andy
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: _destruct : Quick question

Post by pickle »

You should always call exit() after a header relocation. That should destruct everything.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: _destruct : Quick question

Post by McInfo »

pickle wrote:You should always call exit() after a header relocation. That should destruct everything.
There are a few exceptions. You should usually call exit() after header relocation.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Wed Jun 16, 2010 4:07 pm, edited 1 time in total.
User avatar
andyhoneycutt
Forum Contributor
Posts: 468
Joined: Wed Aug 27, 2008 10:02 am
Location: Idaho Falls

Re: _destruct : Quick question

Post by andyhoneycutt »

McInfo wrote:I found a clue.
PHP Manual wrote:Note: Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
I was using a relative path for file_put_contents(). When the current working directory changed, the file was saved to a different location. After changing to an absolute path, the file was saved in the same location every time. That indicates that the destructor was called every time.
Very cool. Thanks for the info :)
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: _destruct : Quick question

Post by McInfo »

marty pain wrote:user defined _destruct functions
This seems unlikely to be the problem since you wrote it correctly later, but make sure you are using two underscores.

Code: Select all

function __destruct () {}
         ^^
Edit: This post was recovered from search engine cache.
Last edited by McInfo on Wed Jun 16, 2010 4:08 pm, edited 1 time in total.
Post Reply