PHP: Constructors - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Scope Resolution Operator (::) extends

Last updated: Sat, 27 Jan 2007

view this page in

# Constructors

Constructors are functions in a class that are automatically called when you create a new instance of a class with `new`. A function becomes a constructor, when it has the same name as the class. If a class has no constructor, the constructor of the base class will be called, if it exists.

`<?php
class Auto_Cart extends Cart {
function Auto_Cart() {
$this->add_item("10", 1);
}
}
?>`

This defines a class Auto_Cart that is a Cart plus a constructor which initializes the cart with one item of article number "10" each time a new Auto_Cart is being made with "new". Constructors can take arguments and these arguments can be optional, which makes them much more useful. To be able to still use the class without parameters, all parameters to constructors should be made optional by providing default values.

`<?php
class Constructor_Cart extends Cart {
function Constructor_Cart($item = "10", $num = 1) {
$this->add_item ($item, $num);
}
}
// Shop the same old boring stuff.
$default_cart = new Constructor_Cart;
// Shop for real...
$different_cart = new Constructor_Cart("20", 17);
?>`

You also can use the `@` operator to mute errors occurring in the constructor, e.g. `@new`.

`<?php
class A
{
function A()
{
echo "I am the constructor of A.<br />\n";
}
function B()
{
echo "I am a regular function named B in class A.<br />\n";
echo "I am not a constructor in A.<br />\n";
}
}
class B extends A
{
}
// This will call B() as a constructor
$b = new B;
?>`

The function B() in class A will suddenly become a constructor in class B, although it was never intended to be. PHP 4 does not care if the function is being defined in class B, or if it has been inherited.

Предостережение
PHP 4 doesn't call constructors of the base class automatically from a constructor of a derived class. It is your responsibility to propagate the call to constructors upstream where appropriate.

Destructors are functions that are called automatically when an object is destroyed, either with unset() or by simply going out of scope. There are no destructors in PHP. You may use register_shutdown_function() instead to simulate most effects of destructors.

add a note User Contributed Notes
Constructors
dexen at NOSPAM dot example dot com
18-Jan-2006 02:44
`Destructors aren't supported in PHP, and the sollution of using 'register_shutdown_function()' isn't really suitable for situations when you wan to perform destructor-alike finalization at a PARTICULLAR MOMENT, possibly way before exiting the PHP machine. (or sort of specialized serialization, as it's in my case).
Anyway, the general problem is to PROPAGATE a call through a hierarchy of objects, based on NAME PATTERN, in right ORDER (most_derived-to-most_base). Do not rely on INCLUSION of any CODE in derived classes. Do not assume EXISTENCE of any of 'destruction' functions. Do support DEEP inheritance.
All i did was to create a _FINI_ function in base class, that calls a 'destructor alike' functions of pattern _%CLASSNAME_. Now, in order to 'destruct' (or serialize) i do $OBJ->_FINI_(); then i can safely unset ($OBJ), all data is already saved to remote storage.
So, if ExSOMETHING derives from ExSession, which in turn derives from ExObject, i create _ExSOMETHING_ function in class ExSOMETHING and _ExObject_ in class ExObject. Notice there's no _ExSession_, yet nothing breaks.
Code:
<?php
class ExObject {
function _FINI_()
{
$p = get_class($this);
while( $p ) {
$px = '_'.$p.'_';
if ( method_exists($this, $px) ) {
$this->$px();
}
$p = get_parent_class( $p );
}
}
}
?>
You may want to create an interface class Destructable, include _FINI_ in it and derive all relevant classes from it.`
mark at dreamjunky dot com
29-Jun-2005 09:57
`Responding to zax AT email DOT cz and others on the topic of pass/fail tests in constructors.
Later versions of PHP don't allow $this = null, so that's out.
Using unset($this) is allowed but is not reliable.
Consider the following:
class a {
function a($pass) {
if (!$pass) unset($this);
}
}
echo ($a = new a(true) ? "Passed" : "False") . "\n";
echo ($a = new a(false) ? "Passed" : "False") . "\n";
The output:
False
False
However, if you add a member variable to the class and run the same script, the output becomes:
Pass
Pass
Basically the object evaluates to false if there are no member variables, otherwise true. I'm guessing, but I believe calling unset($this) only unsets the reference to the object. A copy of it is still passed back to the calling code.
To sum up, I would stick with the original recommended solution of having a property specifically to represent an object's status: initialized or failed.
class A {
var $success;
function A() {
if (/* some fail test */)
$this->success = false;
// rest of your construct
}
}`
jfonseca at matarese dot com
18-May-2005 07:07
`This will save you time if you're building a class hierarchy with 2 or more levels of inheritance.
$this always refers to the CURRENT INSTANCE. Therefore if you have:
class A{
function A(){
}
// ....
}
class B extends A{
function B(){
// keep these 2 lines in mind
$parentClass = get_parent_class($this);
$this->$parentClass();
}
// ....
}
class C extends B{
function C(){
$parentClass = get_parent_class($this);
$this->$parentClass();
// here you will get into an infinite loop calling B();
}
// ....
}
Explanation: $this is an instance variable referring to the CURRENT INSTANCE, therefore the $this variable on class B will always be an instance of C, therefore get_parent_class($this) in class B will call the constructor of C's parent class, which is B again.
This is a hard to track error if you're a novice on PHP's OO features mainly because PHP will not produce any warnings, errors or notices, nor will it log anything to Apache or the error_log file.
Keywords : infinite recursion, parent constructor, subclass`
phpnotes at ionws dot com
04-Apr-2005 10:51
`Just to possibly clarify something on this page: if you create an object of a derived class and the derived class has no constructor, then the base class's constructor will be automatically called. For example:
<?php
class A {
function A() {
echo "A()\n";
}
}
class B extends A {
function foo() {
}
}
$bar = new B;
// output: A()
?>
But if the derived class has a constructor, the base constructor is not automatically called. For example:
<?php
class A {
function A() {
echo "A()\n";
}
}
class B extends A {
function B() {
echo "B()\n";
}
function foo() {
}
}
$bar = new B;
// output: B()
?>`
herojoker at nexgo dot de
28-Feb-2005 07:28
`Hi!
If you want to call the parent's constructor without knowing its name, just call
$this->{get_parent_class(__CLASS__)}($arg1, $arg2, ...);
Have fun with that.
Hero Wanders`
john dot q dot webmaster at gmail dot com
25-Jan-2005 05:55
`When testing the final example, I'm getting conflicting results with what the manual says.
-----
In PHP 3, the function B() in class A will suddenly become a constructor in class B, although it was never intended to be....
This is fixed in PHP 4 by modifying the rule to: 'A constructor is a function of the same name as the class it is being defined in.'. Thus in PHP 4, the class B would have no constructor function of its own and the constructor of the base class would have been called, printing 'I am the constructor of A.<br />'.
-----
I've just tested this on two systems, PHP (module) 4.3.7 and (CGI) 4.3.10. BOTH of them print out the contents of B() when creating a new object of B. This is contrary to the manual, which says this should only happen in PHP 3.
However, when testing the second to last example (where B() has no constructor), the behavior indicated for PHP 4 DOES happen; a constructor is called for 'new B', and it prints "I am the constructor of A.<br />".
What's happening here?`
arjini at gmail dot com
23-Dec-2004 08:02
`This wasn't apparent in the docs above (wording maybe?)
class A{
function A(){
echo 'A\'s constructor has been called.';
}
}
class B {function C(){}}
$instance = new B();
//output: A's constructor has been called.`
zax AT email DOT cz
02-Sep-2004 02:43
`to: steffen-staehle at NO dot SPAM dot gmx dot de
I got an error by
$this=NULL
(Fatal error: Cannot re-assign $this ...),
you should use
unset($this)
instead, that works`
23-Jun-2004 03:48
`This is for Ivan...
If this is the case then what is the case of the constructors of the child class being defined in the parent class...
they also get called implicitly on anyinstance of the child class`
31-Mar-2004 06:50
`to propagate the call to constructors, here is a good method :
class B extends A
{
var $var2;
function B ($arg)
{
parent::A(); // Invoke the constructor of the parent.
}
}`
steffen-staehle at NO dot SPAM dot gmx dot de
01-Dec-2003 09:07
`[in reply to ogarbe's comment (01-Apr-2003)]
Any object evaluation as boolean of the kind
<?
if ($a = new A())
{
// success, use $a ...
}
?>
is dangerous. Whether an object evaluates as true or false seems to depend on its internal structure (I've tested on a rather oldish version of php (4.2.1), though, so this might have changed!). Even a successfully created object might evaluate as false. Compare the two classes:
<?
class TestBool1
{
var $somevar = 'hello world';
function TestBool1()
{
echo "1 somevar is: $this->somevar<p>";
} // constructor
} // TestBool
if ($obj = new TestBool1())
echo 'obj is valid<p>';
else
echo 'obj is invalid<p>';
class TestBool2
{
function TestBool2($somevar)
{
echo "2 somevar is: $somevar<p>";
} // constructor
} // TestBool
if ($obj = new TestBool2('hello world'))
echo 'obj is valid<p>';
else
echo 'obj is invalid<p>';
?>
The output is:
1 somevar is: hello world
obj is valid
2 somevar is: hello world
obj is invalid
Case '2' is NOT what you would expect.
So at least you should use another comparison:
<?
class TestBool3
{
function TestBool3($somevar)
{
echo "3 somevar is: $somevar<p>";
// assume error
$this = NULL;
} // constructor
} // TestBool
if (($obj = new TestBool3('hello world')) !== NULL)
echo 'obj is valid<p>';
else
echo 'obj is invalid<p>';
?>
This evaluates correctly and prints:
3 somevar is: hello world
obj is invalid
But Markus 16-Sep-2003 says assigning NULL to $this did not work any more with php 4.3.3. So what it boils down to: I still prefer the solution I have sketched below (steffen 17-Jan-2003).`
20-Sep-2003 04:08
`Adding to the last post...
If u DON'T WANT to override the parent creator just put
<?
// ...
function On_Create() {
parent::On_Create();
// Some code
}
//...
?>
It will calls the parent creator and u can extend how many classes do you even want to...`
pigmeu at pigmeu dot net
19-Sep-2003 03:30
`To workaround the problem that some people are having on multiple creator (or sub creators or whatever)...
Its just to use an event! Yes... U can emulate an event (like the inprize people do)
Here it goes:
<?
//This is the "generic" class... All other classes may extends from it...
class TObject {
function On_Create() { }
function TObject() {
$this->On_Create();
}
}
class TExtendedObject extends TObject {
var $name;
function On_Create() {
$this->name = "Test";
}
}
$t_class = new TExtendedObject;
echo $t_class->name;
/* output
Test
*/
?>
Nice... Isn't it?`
markus at emedia-solutions-wolf dot de
16-Sep-2003 03:00
`Setting $this to null isn't available in PHP 4.3.3R3 anymore. Maybe in version below also.`
johan_php at popbandetleif dot cjb dot net
06-Apr-2003 05:31
`/**
* Example Class for getting around the problem with
* overloaded functions constructors.
*
* This exapmple are asuming that you want to overload
* the constructor Object() with different arguments.
*/
class Object {
/**
* The real constuctor for this class.
*
* NOTE: Parlameter may not have the value null
* unless you changes the default value in
* the constructor.
*/
function Object($param1 = null, $param2 = null) {
$numargs = func_num_args();
$arg_list = func_get_args();
$args = "";
for ($i = 0; $i < $numargs && $arg_list[$i] != null; $i++) {
if ($i != 0) {
$args .= ", ";
}
$args .= "\$param" . ($i + 1);
}
// Call constructor function
eval("\$this->constructor" . $i . "(" . $args . ");");
}
/**
* Functiorn that will be called if constructor is called
* with no parlameter as agument.
*/
function constructor0() {
echo("Constructor 1: No parlameter." . "\n");
}
/**
* Functiorn that will be called if constructor is called
* with one parlameter as agument.
*/
function constructor1($param) {
echo("Constructor 2: \$param=" . $param . "\n");
}
/**
* Functiorn that will be called if constructor is called
* with two parlameter as agument.
*/
function constructor2($param1, $param2) {
echo("Constructor 3: \$param1=" . $param1 . "\n");
echo("Constructor 3: \$param2=" . $param2 . "\n");
}
}
new Object();
new Object("A String value");
new Object("Another String...", 1);
// Output:
Constructor 1: No parlameter.
Constructor 2: $param=A String value
Constructor 3: $param1=Another String...
Constructor 3: $param2=1`
johan_php at popbandetleif dot cjb dot net
03-Apr-2003 12:39
`As far as I understand php has a strange way of handeling over loaded contructors - only the last defined will be used.
e.g.
class Cl {
function Cl($a, $b) {
echo("B ");
}
function Cl($a) {
echo("A ");
}
}
new Cl(1);
new Cl(1, 2);
// Out puts:
// B B
// And at the contrary:
class Cl {
function Cl($a, $b) {
echo("B ");
}
function Cl($a) {
echo("A ");
}
}
new Cl(1);
new Cl(1, 2);
// Out puts:
// Warning: Missing argument 2 for cl() ...`
ogarbe at tf1 dot fr
01-Apr-2003 11:01
`to steffen staehle
If you want your constructor to possibly not create the object
class A
{
function A()
{
// ...
// some error occurred
$this = null;
return;
}
}
if ($a = new A())
{
// success, use $a ...
}`
steffen staehle
17-Jan-2003 08:11
`A note on a constructor's return value:
When creating an instance of a class, 'new' obviously returns the object, not the constructor's return value (if any).
Still, it might be tempting to communicate the success or failure of constructing the object via a return value:
class A
{
function A()
{
// ...
// some error occurred
return FALSE;
}
}
if ($a = new A())
{
// success, use $a ...
}
THIS WILL NOT WORK the way intended.
'new' returns the object, the assignment returns the value of the assignment, i.e. the object, and whether an object evaluates as TRUE does not depend on the constructor's return value.
My preferred solution - set some object property during the construction phase that you can check against explicitely.`
ianyates at yahoo dot com
14-Jan-2003 09:32
`Although not very good practice, I had a use for it.
In PHP you can destroy an object using unset(object instance) from outside of the object, but I needed to destroy the object from within.
After much experimentation, I simply set $this to null within a function inside the object.
This had the desired affect of removing the object from memory.
Note that unsetting $this does not have the same affect.
It would be better practice to set a variable within the object when it needed to be destroyed and then pick this up externally to mark the object as destroyed.
Hope this helps someone.`
dmarsh dot NO dot SPAM dot PLEASE at spscc dot ctc dot edu
18-Sep-2002 11:40
`Manual Destructor Example Code:
class MyObject()
var $x;
function MyObject() {
$x=array();
register_shutdown_function(array(&$this, "UnMyObject"));
}
[...]
function UnMyObject() {
unset($this->$x); // not needed but used to demonstrate the register_shutdown_function
}
}`
eric+nospam at ypass dot net
04-May-2002 01:59
`This works in PHP 4.1.2 and probably versions > 4.x.
Creating an object from a constructor of a different class type can be accomplished.
Note that you can NOT return an object from a constructor. A constructor can never return a value. However, you can set the value of $this to acheive this.
For example:
<?
class A
{
function A()
{
$this = new B();
}
}
class B
{
function iamab()
{
echo "i am an object of class B";
}
}
$a = new A();
echo '$a is a ' . get_class($a) . "\n";
$a->iamab()
?>
would print out:
$a is a b
i am an object of class B`
12-Dec-2001 11:38
`A couple of comments :
<<If a class has no constructor, the constructor of the base
class is being called, if it exists.>>
Actually the constructor of the base class is NOT called.
The child class inherits TWO copies of the father constructor,
one named after the father, one named after the child.
(other methods are also inherited by copy, as stated in the manual!)
The copied method named after the child is being called. For
most purposes this is the same, but beware of static variables.
class bar{
function bar($var = null){
static $methodname = "bar::bar";
if(isset($var)) $methodname = $var;
else echo "$methodname <b"."r>";
}
}
class foo extends bar{
function printMethods(){
bar::bar();
foo::bar();
foo::foo();
}
}
foo::printMethods(); // prints 3 bar::bar
foo::foo('foo::foo');
foo::bar('foo::bar');
foo::printMethods(); // prints bar::bar,foo::bar,foo::foo
$foo = new foo; // prints foo::foo
$bar = new bar; // prints bar::bar
Ivan`
add a note
Scope Resolution Operator (::) extends

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 09:32:46 2007 PST