473,659 Members | 2,722 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Shutdown order

Hi,

I have this code:

class Test
{
public $status = 'dead';
function __construct() { $this->status = 'alive'; }
function __destruct() { echo '<br>__destruct ()'; }
}
$o = new Test;

function shutdown()
{
echo '<br>shutdown() ';
}
register_shutdo wn_function('sh utdown');

function obflush( $s )
{
global $o;
return $s . '<br>obflush() ' . $o->status;
}
ob_start('obflu sh');

Which (using PHP 5.1.4) produces this output:

shutdown()
__destruct()
obflush() alive

I have two questions:

1) I have read that the order in which the three functions are called has
changed previously and is likely to change again in future versions of PHP.
Does this mean I cannot rely on this order at all?

2) Why is $o still "alive" in obflush() even though its destructor has been
called before? The destructor having been called, I would expect global $o
to point to a no longer existing variable (thus, "null").

Greetings,
Thomas
Nov 15 '06 #1
13 2676
Thomas Mlynarczyk wrote:
Hi,

I have this code:

class Test
{
public $status = 'dead';
function __construct() { $this->status = 'alive'; }
function __destruct() { echo '<br>__destruct ()'; }
}
$o = new Test;

function shutdown()
{
echo '<br>shutdown() ';
}
register_shutdo wn_function('sh utdown');

function obflush( $s )
{
global $o;
return $s . '<br>obflush() ' . $o->status;
}
ob_start('obflu sh');

Which (using PHP 5.1.4) produces this output:

shutdown()
__destruct()
obflush() alive

I have two questions:

1) I have read that the order in which the three functions are called has
changed previously and is likely to change again in future versions of PHP.
Does this mean I cannot rely on this order at all?

2) Why is $o still "alive" in obflush() even though its destructor has been
called before? The destructor having been called, I would expect global $o
to point to a no longer existing variable (thus, "null").

Greetings,
Thomas

It doesn't make any difference what order the functions are in - they
are only called when your code calls them directly or indirectly (i.e. a
constructor). So whatever order you call them in is the way they will
be called.

As for the variable - the object is destroyed, the destructor is called.
But that's not what's happening here. You are calling the destructor,
so it acts just like any other function.

Rather, the destructor is called implicitly during script termination or
when the variable goes out of scope. Like a constructor, you should not
be calling a destructor.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
Nov 15 '06 #2
Hi Thomas,

The order in my version of PHP5.1.6 (main/main.c:php_requ est_shutdown):

/* 1. Call all possible shutdown functions registered with
register_shut down_function() */
....php_call_sh utdown_function s(TSRMLS_C);...

/* 2. Call all possible __destruct() functions */
....zend_call_d estructors(TSRM LS_C);...

/* 3. Flush all output buffers */
....php_end_ob_ buffers((zend_b ool)(SG(request _info).headers_ only?0:1)
TSRMLS_CC)...

[...more steps...]

Maybe step 2 only invokes the destructor, leaving de-allocation to be
done later? I don't know for certain. Here's some more comments about
this:

http://www.zend.com/lists/php-dev/200509/msg00064.html
Thomas Mlynarczyk wrote:
Hi,

I have this code:

class Test
{
public $status = 'dead';
function __construct() { $this->status = 'alive'; }
function __destruct() { echo '<br>__destruct ()'; }
}
$o = new Test;

function shutdown()
{
echo '<br>shutdown() ';
}
register_shutdo wn_function('sh utdown');

function obflush( $s )
{
global $o;
return $s . '<br>obflush() ' . $o->status;
}
ob_start('obflu sh');

Which (using PHP 5.1.4) produces this output:

shutdown()
__destruct()
obflush() alive

I have two questions:

1) I have read that the order in which the three functions are called has
changed previously and is likely to change again in future versions of PHP.
Does this mean I cannot rely on this order at all?

2) Why is $o still "alive" in obflush() even though its destructor has been
called before? The destructor having been called, I would expect global $o
to point to a no longer existing variable (thus, "null").

Greetings,
Thomas
Nov 15 '06 #3
Also sprach Jerry Stuckle:
It doesn't make any difference what order the functions are in - they
are only called when your code calls them directly or indirectly
(i.e. a constructor). So whatever order you call them in is the way
they will be called.
But I am not /calling/ these functions - it is PHP that decides when to call
them. I am merely registering two functions and instantiating an object.
As for the variable - the object is destroyed, the destructor is
called. But that's not what's happening here. You are calling the
destructor, so it acts just like any other function.
Where am *I* calling the destructor in my code? I am merely /defining/ the
function __destruct() and I leave it up to PHP to decide when it is to be
executed.
Rather, the destructor is called implicitly during script termination
or when the variable goes out of scope. Like a constructor, you
should not be calling a destructor.
But I am not calling it! Where in my code do I have a line that says
"$o->__destruct();" ?

Greetings,
Thomas
Nov 16 '06 #4
Also sprach pe*******@gmail .com:

[PHP 5.1.6:
(1) registered shutdown functions,
(2) Destructors,
(3) ob buffers]
Maybe step 2 only invokes the destructor, leaving de-allocation to be
done later?
In this case I should not rely upon the behaviour I observed? But as my
object is in global scope, it would seem more logical to me to "keep it
alive" until *after* the last of the three steps (as $GLOBALS should live
that long), in which case its destructor should not be called before.
http://www.zend.com/lists/php-dev/200509/msg00064.html
Thank you for this link. I think, the behaviour described there refers to an
older version (PHP 5.0.5) in which the destructors were called *before* the
shutdown functions. So it does not explain why I should be able to access an
object after its destructor has been called.

Greetings,
Thomas
Nov 16 '06 #5
Thomas Mlynarczyk wrote:
Also sprach Jerry Stuckle:

>>It doesn't make any difference what order the functions are in - they
are only called when your code calls them directly or indirectly
(i.e. a constructor). So whatever order you call them in is the way
they will be called.


But I am not /calling/ these functions - it is PHP that decides when to call
them. I am merely registering two functions and instantiating an object.

>>As for the variable - the object is destroyed, the destructor is
called. But that's not what's happening here. You are calling the
destructor, so it acts just like any other function.


Where am *I* calling the destructor in my code? I am merely /defining/ the
function __destruct() and I leave it up to PHP to decide when it is to be
executed.

>>Rather, the destructor is called implicitly during script termination
or when the variable goes out of scope. Like a constructor, you
should not be calling a destructor.


But I am not calling it! Where in my code do I have a line that says
"$o->__destruct();" ?

Greetings,
Thomas

Oops, I misread your code and your post.

No, you cannot rely on the order in which things are cleaned up. It is
always subject to change.

This is no different than C++, Java or any other OO languages. The
order in which things are cleaned up is never guaranteed.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
Nov 16 '06 #6
Also sprach Jerry Stuckle:
This is no different than C++, Java or any other OO languages. The
order in which things are cleaned up is never guaranteed.
But at least the order of "calling all shutdown functions", "calling all
destructors" and "calling ob buffer function" should be well-determined,
even if the order in which the destructors are called may not be guaranteed.

And this still doesn't explain why I can access an object *after* its
destructor has been called. Strange...

Greetings,
Thomas
Nov 16 '06 #7
Thomas Mlynarczyk wrote:
Also sprach Jerry Stuckle:

>>This is no different than C++, Java or any other OO languages. The
order in which things are cleaned up is never guaranteed.


But at least the order of "calling all shutdown functions", "calling all
destructors" and "calling ob buffer function" should be well-determined,
even if the order in which the destructors are called may not be guaranteed.

And this still doesn't explain why I can access an object *after* its
destructor has been called. Strange...

Greetings,
Thomas

Thomas,

No, those are all undefined.

And you can still access the object because its reference still points
to the object. PHP will destroy the object, but will not alter the
reference to the object. There is no need to - the reference will be
destroyed soon, anyway.

Destructors are meant to clean up the object itself - i.e. for a class
which access a database you could want to close the database connection.
It's never a good idea to have a destructor depend on the state of
another object which itself may be destroyed. The same is true when you
register a shutdown function - that function should not depend on the
state of any objects.

If you must do this, you need to change the destructor in your Test
object to set the state to invalid.

But that also doesn't mean it might not change again in the future. All
of the processing order is undefined.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
Nov 16 '06 #8
On Thu, 16 Nov 2006 21:28:48 +0100, "Thomas Mlynarczyk"
<th****@mlynarc zyk-webdesign.dewro te:
>But at least the order of "calling all shutdown functions", "calling all
destructors" and "calling ob buffer function" should be well-determined,
It looks, from the mailing list post from the other part of the thread, that
they have finally fixed this. It's been broken for a while, and was re-ordered
but was still broken, and now the order makes sense so long as you have quite a
recent version of PHP.
>even if the order in which the destructors are called may not be guaranteed.
>And this still doesn't explain why I can access an object *after* its
destructor has been called. Strange...
The shutdown function ordering didn't make sense previously, so you were
seeing things you shouldn't have seen - objects who had their destructors
already called before the rest of the script had actually run yet.

Then again I suspect that the order of destruction of objects is still
undefined and not actually influenced by any sort of reference graph, so if you
reference other objects in destructors you're still in for an interesting time.

--
Andy Hassall :: an**@andyh.co.u k :: http://www.andyh.co.uk
http://www.andyhsoftware.co.uk/space :: disk and FTP usage analysis tool
Nov 16 '06 #9
If the behavior did change in the future, you might be able to just
call flush() explicitly at the end of your script, to trigger your
output buffer callback before the global objects were finalized.

Thomas Mlynarczyk wrote:
Also sprach pe*******@gmail .com:

[PHP 5.1.6:
(1) registered shutdown functions,
(2) Destructors,
(3) ob buffers]
Maybe step 2 only invokes the destructor, leaving de-allocation to be
done later?

In this case I should not rely upon the behaviour I observed? But as my
object is in global scope, it would seem more logical to me to "keep it
alive" until *after* the last of the three steps (as $GLOBALS should live
that long), in which case its destructor should not be called before.
http://www.zend.com/lists/php-dev/200509/msg00064.html

Thank you for this link. I think, the behaviour described there refers to an
older version (PHP 5.0.5) in which the destructors were called *before* the
shutdown functions. So it does not explain why I should be able to access an
object after its destructor has been called.

Greetings,
Thomas
Nov 17 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
11262
by: j vickroy | last post by:
Hello, I'm trying to understand the behavior of the Python 2.3 logging module (MS Windows 2k) with regard to RotatingFileHandler. The following script illustrates a puzzling problem. What is wrong with this script? Thanks, -- jv
4
7122
by: Bill Sonia | last post by:
I'm written a Windows Service to send e-mails on events like OnStart, OnStop, OnShutDown using System.Web.Mail. It works for everything but OnShutdown. My guess is that once my send mail code is executed, other necessary Windows Services have been terminated before it can actually send the mail. I've updated my HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services registry DependOnService value including SMPTSVC and others. My hope is...
0
1900
by: Allan Bredahl | last post by:
Hi All I am trying to construct an application that is able to cancel a machine shutdown, reboot or logoff. And after performing some stuff to perform the original shutdown order : Shutdown/reboot/logoff. I have tried this : AddHandler Microsoft.Win32.SystemEvents.SessionEnding, AddressOf
3
1189
by: Senthil | last post by:
Hi, I would like to know the code for reboot and shutdown windows xp professional using VB.Net. thanx Senthil
8
4183
by: Bill Sonia | last post by:
I've written a Windows Service to send e-mails on events like OnStart, OnStop, OnShutDown using System.Web.Mail. It works for everything but OnShutdown. My guess is that for OnShutDown, once my send mail code is executed, other necessary Windows Services have been terminated before it can actually send the mail. I've updated my HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services registry DependOnService value including SMPTSVC and...
4
18111
by: Chris Tanger | last post by:
Context: C# System.Net.Sockets Socket created with constructor prarmeters Internetwork, Stream and TCP everything else is left at the default parameters and options except linger may be changed as I find appropriate. I am using the socket asynchronously by calling the BeingSend and BeginReceive calls. I would like to be able to call shutdown and close asynchronously if possible.
6
8752
by: carbon_dragon | last post by:
Ok, so here is the problem. I'm working on a headless server program implemented as a .NET C# Console project. There is a UPS mounted to this server (though not a windows compliant UPS). I can only talk to the UPS over a special device driver. Through this device driver I can detect that the UPS is going to notify Windows 2000 server to shut down. So I start doing a graceful termination. But Windows shuts down pretty quickly and there...
1
3371
by: jlee | last post by:
I'm pretty much a newbie on mysql, and I need some help. I am running mysql Ver 12.22 Distrib 4.0.24, for portbld-freebsd5.4 (i386) on a server hosting an active website. The site's developer uses his own php shopping cart to receive customer orders. The configuration was done via cPanel with no external modifications - which produced no protests when built, ran and connected with no
5
17405
by: Phil Tusa | last post by:
Greetings to all .... I have a need to issue a shutdown and/or Restart Windows XP inside my application. Any help or example code would be appreciated! -- Phil
0
8427
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8746
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8525
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8627
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7356
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1737
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.