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

search for in the

Constructeur> <Les classes : class
Last updated: Fri, 27 Mar 2009

view this page in

extends : héritage

Souvent, vous aurez besoin d'une classe avec des méthodes et fonctions similaires à une autre classe. En fait, il est bon de définir des classes génériques, qui pourront être réutilisées et adaptées à tous vos projets. Pour faciliter cela, une classe peut être une extension d'une autre classe. La classe dérivée hérite alors de toutes les méthodes et variables de la classe de base (cet héritage a de bien que personne ne meurt pour en profiter), mais peut définir ses propres fonctions et variables, qui s'ajouteront. Une classe ne peut hériter que d'une seule autre classe, et l'héritage multiple n'est pas supporté. Les héritages se font avec le mot clé 'extends'.

<?php
class Panier_nomme extends Panier {
    var 
$owner;
  
    function 
set_owner ($name) {
        
$this->owner $name;
    }
}
?>

L'exemple ci-dessus définit la classe Panier_nomme qui possède les mêmes variables que la classe Panier et la variable $owner en plus, ainsi que la fonction set_owner(). Vous créez un panier nominatif de la même manière que précédemment, et vous pouvez alors affecter un nom au panier ou en connaître le nom. Vous pouvez de toutes les façons utiliser les mêmes fonctions que sur un panier classique.

<?php
$ncart 
= new Panier_nomme;    // Création d'un panier nominatif
$ncart->set_owner ("kris");   // Affectation du nom du panier
print $ncart->owner;           // Affichage du nom du panier
$ncart->add_item ("10"1);   // (héritage des fonctions de la classe père)
?>

Ceci est également appelé une relation "parent-enfant". Vous créez une classe parent, et utilisez extends pour créer une nouvelle classe basée sur la classe parent : la classe enfant. Vous pouvez toujours utiliser cette nouvelle classe enfant et en créer une nouvelle basée sur cette classe enfant.

Note: Les classes doivent être définies avant d'être utilisées ! Si vous voulez que la classe Named_Cart étende la classe Cart, vous devez d'abord définir la classe Cart. Si vous voulez créer une autre classe appelée Yellow_named_cart, basée sur la classe Named_Cart, vous devez d'abord définir la classe Named_Cart. Pour faire court : l'ordre dans lequel les classes sont définies est important.



Constructeur> <Les classes : class
Last updated: Fri, 27 Mar 2009
 
add a note add a note User Contributed Notes
extends : héritage
AwaisKazimi
20-Feb-2009 08:26
Hi all,
I have read the contribution note of "tilman dot schroeder at gmx dot de" about printing the parent class name.
I am basically Java Programmer, so I find that this problem basically deals with "type of the object called" and not "the parent class of the method called".
in his example when the following lines of code are run:
1. $one=new one();
2. $one->two();
3. $one->three();
4. $one->one_get_parent_class_name();
5. $one->two_get_parent_class_name();
Then after line (3) the reference variable $one is referring to the "object of class "one". Please refer to line (1) where the actual object of class one is being created.
Now, the reference variable $one calls the constructors/functions of class two and three because they are the parent classes and the their functions are visible to this reference variable. But remember $one is referring to the object of class "one" and the object never forgets its class. So no matter where in the whole program you ask $one about his parent. He will only answer "two"(i.e. no matter from which position you are calling get_parent_class($this), $this only means "the instance" or "the object"). When ever you refer to the object $one variable is referring to by using $this, the object will only tell you "Hey, I belong to the class one and my parent is class two".
Remember: Object never forgets its "type"... Thanks
Neelam Bhatt
10-May-2006 09:44
Tilman I think you are little bit confused about get_parent_class() function.

Actually this function return the 'parent class' of the class, object belong to; with which it is called.

In your example one_get_parent_class_name() and two_get_parent_class_name() are similar functions and are located in different classes. Their behaviour will be same if will be called with same object. Just add the following two line at the end. You will get the better understanding.

$two=new two();
$two->two_get_parent_class_name();
Edward_nl
03-Mar-2006 10:54
If you are using a child-class. Remember to call the constructor of the parent class aswell before you start using it. Otherwise you might get different results then you expected. It is stated in this document, but I got confused by the given example. So, here is my example:

<?php
error_reporting
(E_ALL);

class
test {
  var
$var;

  function
test() {
   
$this->var = 3;
  }
}

class
testing extends test {
   function
testing() {
    
parent::test();
   }

   function
My_test() {
     return
$this->var;
   }
}

$p = new testing();
echo
$p->My_test();
// Returns 3
doedje
12-Feb-2006 09:37
tilman's note is not quite true. He states the fact that php gives wrong information about the parent class. But this is not the case. Php does give correct information about the parent class, to prove that I give the following code:

<?php
class a
{
   function
showInfo()
   {
      print
"I am class " . get_class($this) . ", my parent is " .get_parent_class($this);
   }
}

class
b extends a {}

class
c extends b {}

$myInstanceB = new b();
$myInstanceB->showInfo();
print
"<br />";
$myInstanceC = new c();
$myInstanceC->showInfo();

/*
output:
I am class b, my parent is a
I am class c, my parent is b
*/
?>

The thing is the function showInfo as they were called by my script, are not a member of class a, but are a member of class b and c. They respond accordingly. Showing correct output in the case of get_class and get_parent_class. So don't go blaming php! =]
tilman dot schroeder at gmx dot de
19-Jan-2006 07:24
Hi...
as alan hogan pointed out it is possible to inherit a class from multiple other classes but notice that php does not always give you the right name of the parent class if you are deriving from multiple classes (tested on php 4.4.0):
 
<?php
header
("Content-Type: text/plain");
class
three {
    function
three() {
        echo(
"constructor of three\n");
    }
// end function three
} // end class three
   
class two extends three {
    function
two() {
        echo(
"constructor of two\n");
    }
// end function two
   
function two_get_parent_class_name() {
        echo(
"i am two and my parent is: ".get_parent_class($this)."\n");
    }
// end one_function get_parent_class_name()
} // end class two

class one extends two {
    function
one() {
        echo(
"constructor of one\n");
    }
// end function one
   
function one_get_parent_class_name() {
        echo(
"i am one and my parent is: ".get_parent_class($this)."\n");
    }
// end one_function get_parent_class_name()
} // end class one

$one=new one();
$one->two();
$one->three();
$one->one_get_parent_class_name();
$one->two_get_parent_class_name();

/*
 *    will print out:
 *
 *        constructor of one
 *        constructor of two
 *        constructor of three
 *        i am one and my parent is: two
 *        i am two and my parent is: two // should print out "my parent is: three"
 */
?>

So be careful when dealing with parents within classes ...
However, if you are using parent:: it will give you access to BOTH parent classes:

<?php
header
("Content-Type: text/plain");
class
three {
    function
three() {
        echo(
"three\n");
    }
}
class
two extends three {
    function
two() {
        echo(
"two\n");
    }
}
class
one extends two {
    function
one() {
        echo(
"one\n");
       
parent::two();
       
parent::three();
    }
}
one::one();
/*
 *    will print out:
 *        one
 *        two
 *        three
 */
?>
alan hogan
27-Nov-2005 01:48
Just a note:  It is possible to have a class inherit from multiple other classes, but only in a one-at-a-time linear hierarchy.

So this works, and C gets A and B functions:

<?php
class A {
  public function
af() { print 'a';}
  public function
bark() {print ' arf!';}
}
class
B extends A {
  public function
bf() { print 'b';}
}
class
C extends B {
  public function
cf() { print 'c';}
  public function
bark() {print ' ahem...'; parent::bark();}
}

$c = new C;
$c->af(); $c->bf(); $c->cf();
print
"<br />";
$c->bark();
/**results:**/
//abc
//ahem... arf!
?>

This does NOT work:

<?php
class A {
  public function
af() { print 'a';}
  public function
bark() {print ' arf!';}
}
class
B {
  public function
bf() { print 'b';}
}
class
C extends B, A /*illegal*/ {
  public function
cf() { print 'c';}
  public function
bark() {print ' ahem...'; parent::bark();}
}

$c = new C;
$c->af(); $c->bf(); $c->cf();
print
"<br />";
$c->bark();
//Parse Error
?>
Bash I.
19-Nov-2005 05:43
Here is a simple idea that I use when I need my abstract classes (the inherited classes) implemented before my functional classes.

<?php
   
    $_CLASSES
= array_merge (
       
glob ("classes/*/*.abstract.php"),
       
glob ("classes/*/*.class.php")
    );
   
    foreach (
$_CLASSES AS $_CLASS) {
        require (
$_CLASS);
    }
   
?>
mga at nrd dot lt
18-Apr-2005 02:03
[Editor's note: For an alternative to multiple inheritance, see the dynamic binding via object aggregation in the corresponding section of the manual.]

Multiple Inheritance is not supported but it is easy to emulate it

The example listed above does not show the main advantages of multiple inheritance. I mean, that multiple inheritance is used not for different outputs, but to combain properties ant functionality from different classes.

If you will try to create complex structure based on this example, I am sure, will be big problems regarding member variables values and etc.

In example, each time when you use "inherited" class it is temporarily created!

The main advantage of inheritance is direct incapsulation of member variables and functions. And here are no possibility to use this advantage :(
volte6 at nowhere dot com
31-Mar-2005 06:11
When declaring a class that relies upon another file ( because it extends the class defined in that file ), you should ALWAYS require_once() that file at the top.
This applies even when planning on looping through and including everything in the folder. Use require_once() in your loop, and at the top of the file that NEEDS the include.
tomnezvigin at comcast dot net
07-Mar-2005 01:19
This may seem obvious, but check this scenario. You have a class folder:

+ class
--classA.php
--classB.php
--classC.php
--mainClass.php

Here... classA, classB, classC all extend the mainClass.

If you try to create a function that automatically includes all of the classes in a folder, normally, they are included alphabetically.

When you try to instantiate classC, for example, you will get an error:

"Cannot inherit from undefined class mainClass"

EVEN IF you instantiate the mainClass before you instantiate all of the other classes.

In other words, make sure your primary class is included before all others.
Roy Yong
27-Jan-2005 04:37
I'm not sure if i'm outdated but I think the current PHP version still does not support extension of methods (something that stands between polymorphism and overriding). Hopefully, this could be included in the next release version of PHP!
jo at durchholz dot org
17-Dec-2004 04:54
Multiple inheritance, if designed properly into the language, most definitely is worth the trouble. Solutions exist for all associated problems (including the name clash issue mentioned above - identify a function by adding the name of the class where is was first defined, and all ambiguities vanish; make the class identification optional if nonambiguous, and it's even backwards-compatible).

The rub is that it's difficult to get a language design that's simple to use, efficiently implementable, and applicable to a dynamically-typed language like PHP.
Msquared
19-Nov-2004 02:48
Multiple inheritence is often more trouble than it's worth.  For example, you have a class foo that inherits from both class bar and class baz.  Classes bar and baz both have a fubar() method.  When you create a foo object and call its fubar() method, which fubar() method is called: bar's or baz's?

It seems to me that using aggregate to glue one class's methods and data to another object is a bit like Ruby's fixins, but I could be wrong...

[[Editor's note:
The aggregate_* functions have been dropped, as of PHP 5
-S
]]
Dave Fancella
14-Mar-2004 03:09
I recommend against using the examples here given for multiple inheritance.

The essential problem is having readable code.  If you want to be able to read your code in a few months, or if you want others to be able to read your code, you're better off using member variables to store class instances than using hacked on multiple inheritance.

One of the big advantages to multiple inheritance in a language that properly supports it like C++ is that you can see, in the class declaration, what it inherits from.  In the example where you extend some class called MultipleInheritance, that only obfuscates your class's ancestry.

So, use inheritance, it's good.  But it's not the be all end all of solutions.  If it were, we wouldn't have templates and various other things in C++.  So don't depend on it.  Instead of asking yourself "How do I use inheritance to solve this problem?" you should ask yourself "Is inheritance the right tool to solve this problem?"  If the language doesn't support multiple inheritance and you're trying to use it anyway, then you have certainly chosen the wrong tool to solve your problem.
efredin at redtempest dot com
03-Mar-2004 01:35
It is possible to override a method innherited from a parent class by simply re-defining the method (for those of us who enjoy using abstract classes).

<?
class A
{
    var $foo;

    function A()
    {
        $this->foo = "asdf";
    }
   
    function bar()
    {
        echo $this->foo." : Running in A";
    }
}

class B extends A
{
    function bar()
    {
        echo $this->foo." : Running in B";
    }
}

$myClass = new B;
$myClass->bar();
?>
robertvanderlinden78 at hotmail dot com
19-Oct-2003 06:50
the model as in the example of "quinton" is what you want to have. Not the method of "kimh216" with function callClass

when calling

    function C()
    {
        //global $a,$b;
        $this->a = parent::callClass('A');//no effect
        $this->b = parent::callClass('B');//no effect
    }

you will not have 1 data object.If i wanted to add a function to class A and i wanted to call it , I can only do it from Class C .. otherwise if I were to do
$c = new C();
$c->someExtraFunctionThatIsInClassA(); it will give an error stating "Fatal error:  Call to undefined function:  functionName() in f:\ibserver\www\meuk\classvbs\test.php.php on line 34"
------------
If i add a new function in Person class of the first example of quinton:
  function boe(){
      echo "some text";
  }

then i can call it by :
$family->members[0]->boe();
since the members array has Personobjects in it. Now you have 1 Object that can access every function as a whole.
regards rml
mazsolt at yahoo dot com
04-Jul-2003 03:49
Just a simple example about inheritance:

class a1{
  var $a=10;
  function a1($a){
     $this->a=$a;
  }
}

class a2 extends a1{
  var $x=11;
  function a2($x,$y){
     $this->x=$x;
     parent::a1($y); // or a1::a1($y) or $this->a1($y)
  }
}

class a3 extends a2{
  var $q=999;
}

$x=new a3(99,9);
echo $x->a,"<br>",$x->x,"<br> ",$x->q;

The output will be:

9
99
999
calimero at creatixnet dot com
23-Jun-2003 03:58
Just a quick note to make things more clear : while multiple inheritance is not allowed, several levels of single inheritance  ARE ALLOWED indeed. Just test this example :
<?
class A {
    var $name='A';

    function disp() {
        echo $this->name;
    }
}

class B extends A {
    var $name='B';
}

class C extends B {
    var $name='C';
}

$truc = new C() ;
$truc->disp(); // Will output C
?>

This is especially important to keep in mind while building a huge object hierarchy. for example :

+GenericObject
->+ Person
->->Employee
->+Computer
->->+WorkStation
->->-> PPC
->->-> Intel
->->+Server
->->->LDAPServer
->->->IntranetWebServer

.. and so on. Multiple level hierarchy relationship are possible in a tree-like structure (each child has one and only one parent, except for the root object).
quinton at free dot fr
10-Jun-2003 08:07
a nice example using extends and multiple classes  and constructors.

<?

class CoreObject {
  var $name;
 
  function CoreObject($name){
    $this->_constructor($name);
  }
 
  function _constructor($name){
    $this->name = $name;
  }

  function show(){
    printf("%s::%s\n", $this->get_class(), $this->name);
  }
 
  function get_class(){
      return get_class($this);
  }
}

class Container extends CoreObject{
 var $members;
 function Container($name){
   $this->_constructor($name);
 }
 
 function &add(&$ref){
   $this->members[] = $ref;
   return ($ref);
 }
 
  function show(){
   parent::show();
   foreach($this->members as $item){
     $item->show();
   }
 }
 function apply(){
 }
}

class Person extends CoreObject{
  function Person($name){
    $this->_constructor($name);
  }
}

class Family extends Container {

 var $members;
 function Family($name){
   $this->_constructor($name);
 }
}

echo "<pre>\n";

$family = new Family('my family');
$family->add(new Person('father'));
$family->add(new Person('mother'));
$family->add(new Person('girl'));
$family->add(new Person('boy'));

$family->show();

print_r($family);

?>
j237fl at hotmail dot com
26-Feb-2003 02:28
This code fragment does NOT seem to work.  It seems as though, the PHP engine when loading a class dosen't set the member vars FIRST, it seems as though it loads the BasicLife member vars before the Super Class methods.

class BasicLife extends Benefit{
    //MEMBER VAR simply REFERS TO METHOD OF SUPER CLASS
    var $simply = Benefit::get_simply();
    //MEMBER VAR me REFERS TO METHOD OF THIS->CLASS
    var $me = $this->get_me();

    function BasicLife(){//CONSTRUCTOR}

    function get_me(){}
   
}
kimh216 at hotmail dot com
29-Oct-2002 01:19
I made some change...
If you don't want to call parent::callClass('A') on the every function which have to call it's parent's method.

//multipleInheritance
class multipleInheritance
{
    function callClass($class_to_call)
    {
        return new $class_to_call();
    }
}

class A
{
    function insideA()
    {
        echo "I'm inside A!<br />";
    }
}

class B
{
    function insideB()
    {
        echo "I'm inside B!<br />";
    }
}

class C extends multipleInheritance
{
    var $a;
    var $b;

    function C()
    {
        //global $a,$b;
        $this->a = parent::callClass('A');//no effect
        $this->b = parent::callClass('B');//no effect
    }
    function insideA()
    {
       // global $a,$b;
        $this->a->insideA();
    }
    function insideB()
    {
        //global $a,$b;
        $this->b->insideB();
    }
    function insideC()
    {
        echo("I'm inside C!<BR>");
    }
}

$c = new C();
$c->insideA();
$c->insideB();
$c->insideC();
novaki at dcs dot vein dot hu
20-Oct-2002 05:13
inheritance from multiple parent classes:

// won't work
class myChildClass extends pClass1, pClass2 {

}

PHP uses aggregation for inheriting from multiple parents, which I think is a bit more complex. See the aggregate function.

(my personal oppinion is that the first method of multiple inheritance should also be imlemented, but I got the answer that it won't be fixed)
"inerte" is my hotmail.com username
27-Sep-2002 08:36
[Editor's note: For an alternative to multiple inheritance, see the dynamic binding via object aggregation in the corresponding section of the manual.]

Multiple Inheritance is not supported but it is easy to emulate it:

class multipleInheritance
{
    function callClass($class_to_call)
    {
        return new $class_to_call();
    }
}

class A
{
    function insideA()
    {
        echo "I'm inside A!<br />";
    }
}

class B
{

    function insideB()
    {
        echo "I'm inside B!<br />";
    }
}

class C extends multipleInheritance
{
    function insideC()
    {
        $a = parent::callClass('A');
        $a->insideA();
        $b = parent::callClass('B');
        $b->insideB();
    }
}

$c = new C();
$c->insideC();
---
This will succesfully echo:
I'm inside A!
I'm inside B!
schultz at rancon dot de
16-Aug-2002 05:37
class a {
  function samename(){
    echo 'a';
} }

class b extends a{
  function samename(){
    echo 'b';
  }
  function b(){
    a::samename();
    b::samename();
} }

$test_obj = new b();

Quiet confusing though, as this prints out 'ab'.
No need to create a new instance of a,
therefor both methods still exists with same name.
griffon9 at hotmail dot com
18-Jul-2002 11:42
Just to clarify something about inheritance. The following code :

class a
{   function call()
     {  $this->toto();
     }
    
     function toto()
     { echo('Toto of A');
     }
}
 
class b extends a
{  function toto()
    { echo('Toto of B');
    }
 }

$b=new b;
$b->call();

...will correctly display "toto of B" (that is, the function declared in the parent is correctly calling the redefined function in the child)
php_AT_undeen_DOT_com
11-Dec-2001 07:31
if the class B that extends class A does not have a constuctor function (i.e. a function named B), then the constructor function of A will be used instead, you don't need to make a constructor in B just to call the constructor of A.

For example:
class A
{
  function A()
    {
      echo "HEY! I'm A!\n";

    }
}
class B extends A
{
}
$b = new B();

produces the output:
HEY! I'm A!
bpotier at edreamers dot org
07-Nov-2001 08:08
Just one thing that may seem obvious but not mentionned in this page is that you need to include/require the file containing the parent class or else you'll get an error:
<?php
require(dirname(__FILE__).'/'.'myParent.php');
...
myChild extends myParent {
...
}
...
?>

Constructeur> <Les classes : class
Last updated: Fri, 27 Mar 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites