PHP  
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
search for in the  
<com_setcall_user_method_array>
view the version of this page
Last updated: Thu, 21 Aug 2003

IX. Class/Object Functions

Introduction

These functions allow you to obtain information about classes and instance objects. You can obtain the name of the class to which an object belongs, as well as its member properties and methods. Using these functions, you can find out not only the class membership of an object, but also its parentage (i.e. what class is the object class extending).

Requirements

No external libraries are needed to build this extension.

Installation

There is no installation needed to use these functions; they are part of the PHP core.

Runtime Configuration

This extension has no configuration directives defined in php.ini.

Resource Types

This extension has no resource types defined.

Predefined Constants

This extension has no constants defined.

Examples

In this example, we first define a base class and an extension of the class. The base class describes a general vegetable, whether it is edible or not and what is its color. The subclass Spinach adds a method to cook it and another to find out if it is cooked.

Example 1. classes.inc

<?php

// base class with member properties and methods
class Vegetable {

    var $edible;
    var $color;

    function Vegetable( $edible, $color="green" ) {
        $this->edible = $edible;
        $this->color = $color;
    }

    function is_edible() {
        return $this->edible;
    }

    function what_color() {
        return $this->color;
    }
    
} // end of class Vegetable

// extends the base class
class Spinach extends Vegetable {

    var $cooked = false;

    function Spinach() {
        $this->Vegetable( true, "green" );
    }

    function cook_it() {
        $this->cooked = true;
    }

    function is_cooked() {
        return $this->cooked;
    }
    
} // end of class Spinach

?>

We then instantiate 2 objects from these classes and print out information about them, including their class parentage. We also define some utility functions, mainly to have a nice printout of the variables.

Example 2. test_script.php

<pre>
<?php

include "classes.inc";

// utility functions

function print_vars($obj) {
    $arr = get_object_vars($obj);
    while (list($prop, $val) = each($arr))
        echo "\t$prop = $val\n";
}

function print_methods($obj) {
    $arr = get_class_methods(get_class($obj));
    foreach ($arr as $method)
        echo "\tfunction $method()\n";
}

function class_parentage($obj, $class) {
    global $$obj;
    if (is_subclass_of($$obj, $class)) {
        echo "Object $obj belongs to class ".get_class($$obj);
        echo " a subclass of $class\n";
    } else {
        echo "Object $obj does not belong to a subclass of $class\n";
    }
}

// instantiate 2 objects

$veggie = new Vegetable(true,"blue");
$leafy = new Spinach();

// print out information about objects
echo "veggie: CLASS ".get_class($veggie)."\n";
echo "leafy: CLASS ".get_class($leafy);
echo ", PARENT ".get_parent_class($leafy)."\n";

// show veggie properties
echo "\nveggie: Properties\n";
print_vars($veggie);

// and leafy methods
echo "\nleafy: Methods\n";
print_methods($leafy);

echo "\nParentage:\n";
class_parentage("leafy", "Spinach");
class_parentage("leafy", "Vegetable");
?>
</pre>

One important thing to note in the example above is that the object $leafy is an instance of the class Spinach which is a subclass of Vegetable, therefore the last part of the script above will output:

[...]
Parentage:
Object leafy does not belong to a subclass of Spinach
Object leafy belongs to class spinach a subclass of Vegetable

Table of Contents
call_user_method_array --  Call a user method given with an array of parameters [deprecated]
call_user_method --  Call a user method on an specific object [deprecated]
class_exists -- Checks if the class has been defined
get_class_methods -- Returns an array of class methods' names
get_class_vars --  Returns an array of default properties of the class
get_class -- Returns the name of the class of an object
get_declared_classes -- Returns an array with the name of the defined classes
get_object_vars -- Returns an associative array of object properties
get_parent_class -- Retrieves the parent class name for object or class
is_a --  Returns TRUE if the object is of this class or has this class as one of its parents
is_subclass_of --  Returns TRUE if the object has this class as one of its parents
method_exists -- Checks if the class method exists


add a note add a note User Contributed Notes
Class/Object Functions
rs98101 at yahoo dot com
12-Sep-2003 01:52
Just a note on good object programming technique...

...a couple of users above have shown ways to split your classes into different files and have them load correctly at runtime, the reason given as something like "to get your classes down to manageable chunks".  This in general is a very BAD idea. 

1) Good design means lightweight objects.  If you find your objects are getting so big that it seems it would make it easier to split them into different files, well, your objects have gotten too complex.  Consider breaking that object into a couple of different ones.  Each object should have 1 clear defined reason to exist, it is a common problem of objects taking on too much responsibility as code evolves over time.  This is often called the "God object", or the "boat anchor". 

2) 99% of the time good programming means writing code that can be easily read and maintained, not code that runs extremely fast in convoluted, obfuscated lines.  Splitting code for 1 object into multiple files would be a maintenance/readability nightmare that would cause any veteran developer to scream in horror.

Happy coding...
mark at g33kz dot co dot uk
09-Sep-2003 08:03
There's an odd quirk with multilevel objects in PHP:

<?PHP

class foo {
  var 
$str;
  function 
foo () {
   
$this->str 'something';
  } 
}

class 
bar {
  var 
$obj;
  function 
bar () {
   
$this->obj = new foo ();
  }
}

$myObj = new bar ();
echo (
'--- '.$myObj->obj->str.' ---');
echo (
"\\n");
echo (
"--- $myObj->obj->str ---");

?>

You would expect this to output:
--- something ---
--- something ---

but instead it outputs:

--- something ---
--- Object->str ---
ar at 5mm de
28-Aug-2003 09:59
I missed some kind of function to dynamicly override or extend an Object:

-----------------------------------------
function &extendObj(&$obj, $code) {
    static $num = 0;
   
    $classname = get_class($obj);
    $newclass = $classname.$num;
   
    eval('class '.$newclass.' extends '.$classname.' { '.$code.' }');
   
    $newobj = new $newclass();

    $vars = get_class_vars($classname);
    foreach($vars AS $key=>$value) {
        $newobj->$key = &$obj->$key;
    }
   
    return $newobj;
}
-----------------------------------------

This creates a new class which extends the old one by the given code parameter, instanciates it and copy all vars from the old obj to the new one.

-----------------------------------------
class testA {
    var $prop = 'a';
   
    function funcA($val) {
        $this->prop = $val;
    }
   
    function value() {
        return $this->prop;
    }
}

$obj = new testA();

$newobj = &extendObj(&$obj, 'function addX() { $this->prop .= "x"; }');

$newobj->funcA('abc');
$newobj->addX();
echo $newobj->value();
-----------------------------------------

Results in 'abcx'. You can use the function multiple times and also with class variables. Be carefull, even if $newobj is just a copy of $obj, $obj->value() will return 'abcx', too, because of the & operator: $newobj->$key = &$obj->$key;
pixellent at stodge dot net
20-Aug-2003 01:07
In case you were wondering, you can't do the following in PHP:

$name = wsConfig::GetInstance()->GetValue("name");

It causes a parse error, I think due to trying to call GetValue. And yes I do have a function called GetValue in my wsConfig class.

This is my singleton:

function &GetInstance()
{
    static $Instance;
    if (!isset($Instance))
    {
        $Instance = new wsConfig();
    }
    return $Instance;
}
zidsu at hotmail dot com
08-Jul-2003 07:24
FYI: if you want to split your class into manageble chunks, what means different files for you, you can put you functoins into includes, and make include() have a return value. Like this:

class Some_class {
  var $value = 3;
  function add_value ($input_param) {
    return include ("path/some_file.php");
  }
}

And your included file:

$input_param += $this->value;
return $input_param;

Then your function call will be:

$instance = new Some_class ();
$instance->add_value (3);

And this will return
6
hopefully :P

Keep in mind though, that the scope in the included file will be identical to the scope the function 'add_value' has.
And if you want to return the outcome, you should also have a return statement made in your include as well.
ninja (a : t) thinkninja (d : o : t) com
11-May-2003 01:37
the best way i found to call an instance of a class from within another class is like so:

class foo {
 
 var $meta = 1;

}

class bar {

 var $foo;

 function bar(&$objref) //constructor
 {
   $this->foo =&  $objref;
 }

 function doohickey()
 {
   return $this->foo->meta;
 }

}

$fooclass = new foo();
$barclass = new bar($fooclass);

echo $barclass->doohickey();
Carlos
05-Apr-2003 07:32
Commenting the above example:

We read: "$int->s(); // now it shows the right value". But no, it it won't, even if expected ;) The s() is buggy and should be:

function s() { echo $this->m[0]; }

then it will work. ;)
info at free-dev dot com
15-Feb-2003 06:03
A constructor (a code with runs in the initialization of the class) can be used, like in the C language. Here's an example :

<?
class int {
 function 
int() { echo "constructor"; }
}
$myint = new int// creates a new instance and call the constructor
?>

The constructor's function name MUST be the same as the class name. If you want to pass arguments in the constructor, use this :

<?
class int {
 function 
int($str) { echo $str; }
}
$myint = new int("hello");
?>

Now you can show hello at the initialization of the class. I tried to see if I could use the destructor (~classname) but it doesn't seems do work :-( it you want to use a variable in a class, you must create a new instance of it. Example :

<?
class {
 var 
$m=array("a""b""c");
 function 
s() { echo $m[0]; }
}
i::s(); // it doesn't work because $m is set to nothing

$int = new i// create instance and sets m
$int->s(); // now it shows the right value
?>
alex at liniumNOSPAM dot net
13-Dec-2002 05:39
Using the good old eval() function, it is possible to dynamically create classes. I found this very useful because I could generate a class dynamically based on the structure of an XML document. For example:

$classString = 'class someClass { var $someVar = "someValue"; }';
eval($classString);
$someObject = new someClass;
echo $someObject->someVar;

This will print "someValue" as expected. This very simple example is pointless, as it would be easier to just create the class in the normal way, but here is where it gets interesting:

$varString = "";
for ($i = 1; $i <= 3; $i++) {
    $varString .= "var \$var$i = $i; ";
}

$classString = "class someClass { $varString }";
eval($classString);

$someObject = new someClass;
echo $someObject->var1;
echo $someObject->var2;
echo $someObject->var3;

This prints 1 2 3. Cool huh?

Now it just so happens that its possible to declare classes within functions, so its actually possible to make a function that will create a class on the parameters you supply to it. Now try doing THAT in ASP!!!
ernest at vogelsinger dot at
24-Oct-2002 09:18
It appears as if "include()" and "require()" cannot appear inside a class definition, but outside a class method.

For example, the construct
    class A {
        include ('class_a_methods.php');
    }
returns an error (unexpected T_INCLUDE), but
    class A {
        function foo() {
            include ('class_a_foo_method.php');
        }
    }
works as expected.

This is a slight annoyance if one wants to keep class code in manageable chunks.
asommer*at*as-media.com
21-Sep-2002 04:52
Something I found out just now that comes in very handy for my current project:

it is possible to have a class override itself in any method ( including the constructor ) like this:

class a {

..function ha ( ) {
....if ( $some_expr ) {
......$this = new b;
......return $this->ha ( );
....}
....return $something;
..}

}

in this case assuming that class b is already defined and also has the method ha ( )

note that the code after the statement to override itself is still executed but now applies to the new class

i did not find any information about this behaviour anywhere, so i have no clue wether this is supposed to be like this and if it might change... but it opens a few possibilities in flexible scripting!!
einhverfr at not-this-host dot hotmail dot com
15-Sep-2002 02:35
You may find it helpful in complex projects to have namespaces for your classes, and arrange these in a hierarchical manner.   A simple way to do this is to use the filesystem to order your hierarchies and then define a function like this:

function use_namespace($namespace){

require_once("namespaces/$namespace.obj.php");

}

(lack of indentation due to HTML UI for this page)
This requires that all your object libraries end in .obj.php (which I use) but you can modfy it to suit your needs.  To call it you could, for exmaple call:

use_namespace("example");
or if foo is part of example you can call:
use_namespace("example/foo");
justin at quadmyre dot com
19-Aug-2002 11:38
If you want to be able to call an instance of a class from within another class, all you need to do is store a reference to the external class as a property of the local class (can use the constructor to pass this to the class), then call the external method like this:

$this->classref->memberfunction($vars);

or if the double '->' is too freaky for you, how about:

$ref=&$this->classref;
$ref->memberfunction($vars);

This is handy if you write something like a general SQL class that you want member functions in other classes to be able to use, but want to keep namespaces separate. Hope that helps someone.

Justin

Example:

<?php

class class1 {
    function 
test($var) {
       
$result $var 2;
        return 
$result;
    }
}

class 
class2{
    var 
$ref_to_class=''# to be pointer to other class

   
function class1(&$ref){ #constructor
       
$this->ref_to_class=$ref#save ref to other class as property of this class
   
}

    function 
test2($var){
       
$val $this->ref_to_class->test($var); #call other class using ref
       
return $val;
    }
}

$obj1=new class1;
# obj1 is instantiated.
$obj2=new class2($obj1);
# pass ref to obj1 when instantiating obj2

$var=5;
$result=obj2->test2($var);
# call method in obj2, which calls method in obj1
echo ($result);

?>
matthew at fireflydigital dot com
29-Apr-2002 11:48
This is a pretty basic data structure, I know, but I come from a C++ background where these things were "da bomb" when I was first learning to implement them. Below is a class implementation for a queue (first-in-first-out) data structure that I used in a recent project at my workplace. I believe it should work for any type of data that's passed to it, as I used mySQL result objects and was able to pass the object from one page to another as a form element.

# queue.php

# Define the queue class
class queue
{
    # Initialize class variables
    var $queueData = array();
    var $currentItem = 0;
    var $lastItem = 0;
   
    # This function adds an item to the end of the queue
    function enqueue($object)
    {
        # Increment the last item counter
        $this->lastItem = count($this->queueData);
       
        # Add the item to the end of the queue
        $this->queueData[$this->lastItem] = $object;
    }
   
    # This function removes an item from the front of the queue
    function dequeue()
    {
        # If the queue is not empty...
        if(! $this->is_empty())
        {
            # Get the object at the front of the queue
            $object = $this->queueData[$this->currentItem];
           
            # Remove the object at the front of the queue
            unset($this->queueData[$this->currentItem]);
           
            # Increment the current item counter
            $this->currentItem++;
           
            # Return the object
            return $object;
        }
        # If the queue is empty...
        else
        {
            # Return a null value
            return null;
        }
    }
   
    # This function specifies whether or not the queue is empty
    function is_empty()
    {
        # If the queue is empty...
        if($this->currentItem > $this->lastItem)
           
            # Return a value of true
            return true;
           
        # If the queue is not empty...
        else
       
            # Return a value of false
            return false;
    }
}

?>

# Examples of the use of the class

# Make sure to include the file defining the class
include("queue.php");

# Create a new instance of the queue object
$q = new queue;

# Get data from a mySQL table
$query = "SELECT * FROM " . TABLE_NAME;
$result = mysql_query($query);

# For each row in the resulting recordset...
while($row = mysql_fetch_object($result))
{
    # Enqueue the row
    $q->enqueue($row);
}

# Convert the queue object to a byte stream for data transport
$queueData = ereg_replace("\"", "&quot;", serialize($q));

# Convert the queue from a byte stream back to an object
$q = unserialize(stripslashes($queueData));

# For each item in the queue...
while(! $q->is_empty())
{
    # Dequeue an item from the queue
    $row = $q->dequeue();
}
c.bolten AT grafiknews DOT de
22-Apr-2002 08:14
another way to dynamically load your classes:

==========================
function loadlib($libname) {
     $filename = "inc/".$libname.".inc.php";
     // check if file exists...
     if (file_exists($filename)) {
          // load library   
          require($filename);
          return TRUE;
     }
      else {
    // print error!
    die ("Could not load library $libname.\n");
     }
}

:)

have phun!

-cornelius
ma++ at ender dot com
21-Mar-2002 02:39
Actually, that example prints "1" and then "1", rather than "1" and then "2". I'm assuming the typo is that it should read $class2 = "b" instead of a.
saryon_no_spam_@unfix dot o r g
06-Mar-2002 01:46
Something nice i found out when i was trying to do with classes what i knew could be done with
functions: they can be dynamically loaded/used.

ex:

class a
{
        function bla()
        {
                echo "1\n";
        }
}

class b
{
        function bla()
        {
                echo "2\n";
        }
}

$class = "a";

$test = new $class;
$test->bla();

$class2 = "a";

$test2 = new $class2;
$test2->bla();

-----------------------

This will print:

1
2

------------------

For those of you who were considering doing something with plugins....use this to your
advantage :)

makes life soooo easy, this :)

Sar
zzz at iz4u dot net
24-Feb-2002 04:34
array in class ^^

class CConfig
{
    var $color = array(
        'top'     => "",
        'write'   => "",
        'reply'   => "",
        'bottom1' => "",
        'bottom2' => "",
        'bottom3' => ""
    );
}

don't do var color['write'];
a2zofciv2 at hotmail dot com
29-Sep-2001 12:10
I spent 20 minutes or so trying to figure this out, maybe someone else has the same problem.

To access a class' function from within the class you would have to say $this->functionname(params), rather than just functionname(params) like in other programming languages.

Hope this helps
kevin at gambitdesign dot com
04-Jun-2001 04:27
i came across an error something to the extent:

Fatal error: The script tried to execute a method or access a property of an incomplete object.

This was because I had included the file defining the class when i created the object but not in the script when i was trying to access the object as a member variable of a different object
gateschris at yahoo dot com
08-Mar-2001 05:59
[Editor's note: If you are trying to do overriding, then you can just interrogate (perhaps in the method itself) about what class (get_class()) the object belongs to, or if it is a subclass of a particular root class.

You can alway refer to the parent overriden method, see the "Classes and Objects" page of the manual and comments/editor's notes therein.]

There is no function to determine if a member belongs to a base class or current class eg:

class foo {
 function foo () { }
 function a () { }
}

class bar extends foo {
 function bar () { }
 function a () { }
}

lala = new Bar();
------------------
how do we find programmatically if member a now belongs to class Bar or Foo.

<com_setcall_user_method_array>
 Last updated: Thu, 21 Aug 2003
show source | credits | sitemap | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: http://php.mirrors.ilisys.com.au/
Last updated: Sat 01 Nov 2003 04:13:36 EST EST