Correction to the previous poster about non public constructors. If I wanted to implement Singleton design pattern where I would only want one instance of the class I would want to prevent instantiation of the class from outside of the class by making the constructor private. An example follows:

Be aware of potential memory leaks caused by circular references within objects. The PHP manual states "[t]he destructor method will be called as soon as all references to a particular object are removed" and this is precisely true: if two objects reference each other (or even if one object has a field that points to itself as in $this->foo = $this) then this reference will prevent the destructor being called even when there are no other references to the object at all. The programmer can no longer access the objects, but they still stay in memory.

// make them point to each other$foo->setLink($bar);$bar->setLink($foo);

// destroy the global references to them$foo = null;$bar = null;

// we now have no way to access Foo 1 or Foo 2, so they OUGHT to be __destruct()ed// but they are not, so we get a memory leak as they are still in memory.//// Uncomment the next line to see the difference when explicitly calling the GC:// gc_collect_cycles();// // see also: http://www.php.net/manual/en/features.gc.php//

// create two more Foo objects, but DO NOT set their internal Foo references// so nothing except the vars $foo and $bar point to them:$foo = new Foo('Foo 3');$bar = new Foo('Foo 4');

// destroy the global references to them$foo = null;$bar = null;

// we now have no way to access Foo 3 or Foo 4 and as there are no more references// to them anywhere, their __destruct() methods are automatically called here,// BEFORE the next line is executed:

Since we are still in the __construct and __destruct section, alot of emphasis has been on __destruct - which I know nothing about. But I would like to show the power of parent::__construct for use with PHP's OOP polymorphic behavior (you'll see what this is very quickly).

In my example, I have created a fairly robust base class that does everything that all subclasses need to do. Here's the base class def.

<?php

/* * Animal.php * * This class holds all data, and defines all functions that all * subclass extensions need to use. * */abstract class Animal{ public $type; public $name; public $sound;

Declaring Animal as abstract is like killing two birds with one stone. 1. We stop it from being instantiated - which means we do not need a private __construct() or a static getInstance() method, and 2. We can use it for polymorphic behavior. In our case here, that means "__construct", "__toString" and "compare" will be called for all subclasses of Animal that have not defined their own implementations.

The following subclasses use parent::__construct(), which sends all new data to Animal. Our Animal class stores this data and defines functions for polymorphism to work... and the best part is, it keeps our subclass defs super short and even sweeter.

# create a PHP Array and initialize it with Animal objects$animals = array( new Dog("Fido"), new Bird("Celeste"), new Cat("Pussy"), new Dog("Brad"), new Bird("Kiki"), new Cat("Abraham"), new Dog("Jawbone"));

Using parent::__construct() in a subclass and a super smart base class, gives your child objects a headstart in life, by alleviating them from having to define or handle several error and exception routines that they have no control over.

Notice how subclass definitions are really short - no variables or functions at all, and there is no private __construct() method anywhere? Notice how objects of type Dog, Cat, and Bird are all sorted by our base class Animal? All the class definitions above address several issues (keeping objects from being instantiated) and enforces the desired, consistent, and reliable behavior everytime... with the least amount of code. In addition, new extenstions can easily be created. Each subclass is now super easy to redefine or even extend... now that you can see a way to do it.

Peter has suggested using static methods to compensate for unavailability of multiple constructors in PHP. This works fine for most purposes, but if you have a class hierarchy and want to delegate parts of initialization to the parent class, you can no longer use this scheme. It is because unlike constructors, in a static method you need to do the instantiation yourself. So if you call the parent static method, you will get an object of parent type which you can't continue to initialize with derived class fields.

Imagine you have an Employee class and a derived HourlyEmployee class and you want to be able to construct these objects out of some XML input too.

Being new to OOP, it took me quite a while to figure out that there are TWO underscores in front of the word __construct.

It is __constructNot _construct

Extremely obvious once you figure it out, but it can be sooo frustrating until you do.

I spent quite a bit of needless time debugging working code.

I even thought about it a few times, thinking it looked a little long in the examples, but at the time that just seemed silly(always thinking "oh somebody would have made that clear if it weren't just a regular underscore...")

All the manuals I looked at, all the tuturials I read, all the examples I browsed through - not once did anybody mention this!

(please don't tell me it's explained somewhere on this page and I just missed it, you'll only add to my pain.)

conclusions:destructors are always called on script end.destructors are called in order of their "context": first functions, then global objectsobjects in function context are deleted in order as they are set (older objects first).objects in global context are deleted in reverse order (older objects last)

shutdown functions are called before the destructors.shutdown functions are called in there "register" order. ;)

// use a unique id for each derived constructor, // and use a null reference to an array, // for optional parametersfunction __construct($id="", $args=null) {// parent constructor called first ALWAYSparent::__construct();

While experimenting with destructs and unsets in relation to memory usage, I found what seems to be one useful way to predict when __destruct() gets called... call it manually yourself.

I had previously assumed that explicitly calling unset($foo) would cause $foo->__destruct() to run implicitly, but that was not the behavior I saw (php 5.2.5). The destructors weren't running until the script ended, even though I was calling unset($foo) in the middle of my script. So, having $foo->__destruct() unset all of $foo's component objects was not helping my memory usage since my explicit unset($foo) was _not_ triggering $foo->__destruct()'s cleanup steps.

Interestingly, what _did_ appear to happen is that calling unset($bar) from inside a destructor like $foo->__destruct() _DID_ cause $bar->__destruct() to be implicitly executed. Perhaps this is because $bar has a "parent" reference of $foo whereas $foo does not, and the object destruction behaves differently... I don't know.

Lastly, even after explicitly calling $foo->__destruct() (even when it had "unset($this);" inside it), the reference to the $foo object remained visible. I had to still explicitly call unset($foo) to get rid of it.

With the destructor if you're going to write to a file make sure you have the full file path and not just the filename, it seems PHP switches the working directory to the apache root directory when exiting the script.

The above will result in an error:Notice: Undefined property: my_class::$error_reporting in my_class.php on line 10

It appears as though the variable will be unset BEFORE it actually can execute the if statement. Removing the unset will fix this. It's not needed anyways as PHP will release everything anyways, but just in case you run across this, you know why ;)

It's usefull to note that parent::__construct() is executed like a standalone function called into the new one, and not like a first part of the code. So "return" or "die()" don't have effect on following code. If you want to avoid the execution of the child constructor you have to pass some condition from the parent. Example:

Another way to overcome PHP's lack of multi constructors support is to check for the constructor's parameters' type and variate the operation accordingly. This works well when the number of parameters stays the same in all your constructors' needs.

The manual page says that throwing an exception from a destructor causes a fatal error; I've found that this only happens when the exception is _uncaught_ within the context of that destructor. If you catch it within that same destructor it seems to be fine.

This is equally true of other contexts, such as:- shutdown functions set with register_shutdown_function- destructors- custom session close functions- custom error handlers- perhaps other similar contexts

An exception normally 'bubbles up' to higher and higher contexts until it is caught, but because a destructor or shutdown function is called not within execution flow but in response to a special PHP event, the exception is unable to be traced back any further than the destructor or shutdown function in which it is called.

For those who still ***have*** to deal with php4 (like myself, which sucks), contact at tcknetwork dot com noted below that you can have both __constructor and function [classname] in the script, as __constructor has priority.

However, to further improve compatability, do a version check in function [classname], as I do in my classes as follows:<?phpclass Foo{ function __construct($arg){ echo $arg; }

The fact that $obj1 is useless and cannot be used as a reference, is further evidence that MyClassB objects should not be instantiated. NOTICE that MyClassB does not use private members or functions to make it behave that way. Rather, it is the collective nature of all the class members + what ISN'T there.

I ran into an interesting (and subtle) code error while porting some code to PHP 5.2.5 from PHP 4.4.8 that I think illustrates a noteworthy semantic.

I have a hierarchy of classes with both styles of constructors but where one in the middle was missing the __construct() function (it just had the old-style one that called the (nonexistent) __construct()). It worked fine in PHP4 but caused an endless loop (and stack overflow) in PHP5. I believe what happened is that in PHP4 the old-style constructor was not called, but in PHP5 it was (due to the "emulation" of PHP4), and since _construct() wasn't defined for that class, the call to $this->__construct() caused a looping call to the original (lowest child) constructor.

Since my last note, I've been instructed to _NEVER_ call "unset($this)", never ever ever. Since my previous testing of behavior did not explicitly show me that it was indeed necessary, I'm inclined to trust those telling me not to do it.

I too was having the same problem with Class Constructor visibility, in which I had one Class that was extended by several other Classes. The problem that I encountered was in one of the Child Classes, I wanted a weaker visibility. Consider the following example:

<?php

class A {

// Public Constructor ... // No Problems Here.

public function __construct( ) {

}

// Class Function.

public function functionA( ) {

}}

class B extends A {

// Public Constructor ... // Same As Parent Class ... // Again No Problems Here.

Nothing new in the above example that we have not seen before. My solution to solve this problem?

Create an Abstract Class with all the functionality of Class A. Make its Class Constructor have a visibility of Protected, then extend each of the three Classes above from that Abstract Class. In a way, the Abstract Class acts as a dummy Class to get rid of the visibility problem:

// By Moving All The Functionality Of // Class A To Class AAbstract Class A // Will Automatically Inherit All Of // Its Functionality. The Only Thing // Left To Do Is To Create A Constructor // Which Calls Class AABstract's Constructor // To Mimic Similar Behavior.

parent::__construct( ); }

// No Need To Redeclare functionA( ) // Since It Was Moved To Class // AAbstract.}

As you can see the problem is more or less fixed. Class AAbstract acts a dummy class, containing all the original functionality of Class A. But because it has a protected Constructor, in order to make its functionality available, Class A is redeclared as Child Class with the only difference of it having a public Constructor that automatically calls the Parent Constructor.

Notice that Class B does not extend from Class A but also from Class AAbstract! If I wanted to change Class B's Constructor to protected, I can easily do it! Notice that an extra Method was added to Class B ... this is because Class B has extra functionality specific to itself. Same applies to Class C.

Why don't Class B and Class C extend from Class A? Because Class A has a public Constructor, which pretty much defies the point of this solution.

I recently found, while implementing a database backed session class, that PHP has an apparently less than desirably structured destruction order. Basically, my session class which would have saved when destructed, was being destructed after one of the classes it depends on. Apparently we cannot, therefore depend on PHP to use reverse initialisation order.

My solution was to use register_shutdown_function, which is called before any objects are killed on script end.

You then can call with or without arguments without having notices and/or warnings thrown at you... Of course this is limited but if you don't need something complex this can help to get the job done in some situations. I believe you could also add arguments to the __construct() function and as long as it is different than Example() 's args you would be fine. Although I have yet to test this.

What you could do is write the constructor without any declared arguments, then iterate through the arguments given and check their types/values to determine what other function to use as the constructor.

This is just to clarify that the Singleton pattern is a bit more complex than just making the constructor private. It also involves caching an instance of the object and always returning the cached value. So, in the previous example, the getNewInstance() function would undermine the intent of the Singleton pattern. Instead you would just need a getInstance() function, like so.

The manual says:"Like constructors, parent destructors will not be called implicitly by the engine."

This is true ONLY when a __destruct() function has been defined by the child class.If no __destruct() function exists in the child class, the parent's one will be implicitly executed.

So be carefull if you have some ancestor executing a particular task in its __destruct() function, an you plan its childs to execute it or not, wether you include "parent::__destruct()" or not.If you want the child not to execute its parent __destruct() function, you must ensure that it has its own __destruct() function, even if empty. Then the parent's one will not be executed.

public static function destroyAfter(&$obj) { self::getInstance()->objs[] =& $obj; /* Hopefully by forcing a reference to another object to exist inside this class, the referenced object will need to be destroyed before garbage collection can occur on this object. This will force this object's destruct method to be fired AFTER the destructors of all the objects referenced here. */ } public function __construct($key) { $this->C = new SimpleCrypt($key); ob_start(array($this,'getBuffer')); } public static function &getInstance($key=NULL) { if(!self::$_me && $key) self::$_me = new EncryptedComms($key); else return self::$_me; }

public function __destruct() { ob_end_flush(); }

public function getBuffer($str) { return $this->C->encrypt($str); }

}

In this example, I tried to register other objects to always be destroyed just before this object. Like this:

class A{

public function __construct(){ EncryptedComms::destroyAfter($this);}}

One would think that the references to the objects contained in the singleton would be destroyed first, but this is not the case. In fact, this won't work even if you reverse the paradigm and store a reference to EncryptedComms in every object you'd like to be destroyed before it.

In short, when a script die()s, there doesn't seem to be any way to predict the order in which the destructors will fire.

Hello, I've been messing with php for about a week but am learning a lot. It occurred to me that it might be necessary in some cases to write a class that takes a variable number of arguments. After some experimentation, this example was formed:

This is a simple thing to bear in mind but it's also easy to forget it. When chaining object constructors and destructors, always remember to call the superclass __construct() method in the subclass __construct() so that all superclass members are properly initialized before you start initializing the ones belonging to your subclass.

Also, you will usually want to do your own cleanup first in your subclass __destruct() method so you will probably want to call the superclass __destruct() as the last thing in your subclass so that you can use resources defined in the superclass during the cleanup phase.

For example, if your superclass includes a database connection and your subclass __destruct method commits things to the database then if you call the superclass destruct before doing so then the database connection will no longer be valid and you will be unable to commit your changes.

After uncommenting the // comment, the output will change tocontained containing

Adding a reference from the contained class to the containing one (the # comment) will not change that, but beware, because it can cause random errors in other destructors in the parts of the script which seem unrelated! (PHP Version 5.1.2)

__construct and __destruct must be declared public in any class that you intend to instantiate with new. However, in an abstract (or never-instantiated base) class you can declare them private or protected, and subclasses can still refer to them via parent::__construct (!) (tested in PHP 5.1.2).

be careful while trying to access files with __destruct() because the base directory (getcwd()) will be the root of your server and not the path of your script, so add before all your path called in __destruct() :EITHER dirname($_SERVER["SCRIPT_FILENAME"])."my/path/"OR dirname(__FILE__)."my/path/" (be careful with includes, it will give the path of the file processed and not the main file)

Php 5.3.3 had a very strange bug, related to __destruct, but this bug was fixed in 5.3.6. This bug happened to me and it took me forever to figure it out, so I wanted to share it.

In short, don't unset properties in __destruct():<?phpclass Foobar { public $baz; function __destruct() {# Don't do either of these, if $baz also has a __destruct()!$this->baz = null; unset($this->baz);

# Instead, don't clear it at all, or do this:$this->baz->__destruct(); }}?>

If you made this mistake, this might happen in php<5.3.6:<?php# Some function that throws an exceptionfunction fail($foobar) { throw new Exception("Exception A!");}

I just thought I'd share some valuable information that might help novice programmers/scripters in __constructor() functions.

I've been using PHP for quite a long time, as well as programming and scripting in general. Even with my quite seasoned skillset, I still make obvious, painstaking mistakes. That said, I'd like to point out one major (albeit obvious) common mistake that programmers and scripters (such as myself) make.

When defining the constructor for an object and using it to populate variables for use throughout the lifetime of the application, do note that if you set a static variable AFTER a dynamic one, the static variable's (intended) contents are not readible inside the assigning functions of a dynamic variable. (That sounded rather cryptic, so an example is in order...)

<?phpclass ExampleClass{// assigned a static value using an expression in the constructorpublic $myStaticVar;

// assigned a value through a function of the classpublic $myDynamicVar;

public function __construct3($optional = null) { die('Third construct'); } }?>You can define as much constructors as you wish and limit them by php's type hinting. Note that the constructor signatures should be non-ambiguous.

If you don't need PHP 4, just delete the Foo function. Or you reverse the order of Foo and __construct, the error goes away, so that's probably OK for a single class. Also there was a suggestion to do this in Foo:<?phpfunction Foo() { if (version_compare(PHP_VERSION,"5.0.0","<")) { return $this->__construct(); } }?>

Note that php5 use in priority __construct() instead of [classname](). So you could build a constructed/destructed class for php4/5 very easily using this.<?class test { function test() {$this->__construct();register_shutdown_function(array($this,"__destruct")); } function __construct() { echo "construct\n"; } function __destruct() { echo "destruct\n"; }};$t=new test();?>In case you use unset($t) in php4, the destructor is not called. so be careful.

I would advise against the use of exceptions within __construct. If you store the error code for an exception within a function of that class, you have no way of reading that error code to tell what type of exception it is because the object does not exist yet.

As far as I can tell, Connection: close isn't sent until after __destruct is called in shutdown sequence.I was hoping to get the HTTP connection closed and done, and do some slow non-output processing after that, but no luck.

If you're using E_STRICT error reporting, PHP will tell you if you define both __construct() and an old-style constructor (a function with the same name as the class) together in a class. Note that this occurs even if the old constructor function is abstract or final (for instance, if you were intending to only use it in a sub-class). Be wary of this if you're trying to implement the 'command' design pattern.

The solution? Either turn E_STRICT off (and possibly forgo some other important notices), rename your function (and possibly make things a little more complicated), or look at using an interface.