get_object_vars

(PHP 4, PHP 5)

get_object_vars -- 返回由对象属性组成的关联数组

描述

array get_object_vars ( object obj )

返回由 obj 指定的对象中定义的属性组成的关联数组。

注: 在 PHP 4.2.0 之前的版本中,如果在 obj 对象实例中声明的变量没有被赋值,则它们将不会在返回的数组中。而在 PHP 4.2.0 之后,这些变量作为键名将被赋予 NULL 值。

例子 1. 使用 get_object_vars()

<?php
class Point2D {
    var
$x, $y;
    var
$label;

    function
Point2D($x, $y) {
        
$this->x = $x;
        
$this->y = $y;
    }

    function
setLabel($label) {
        
$this->label = $label;
    }

    function
getPoint() {
        return array(
"x" => $this->x,
                     
"y" => $this->y,
                     
"label" => $this->label);
    }
}

// "$label" is declared but not defined
$p1 = new Point2D(1.233, 3.445);
print_r(get_object_vars($p1));

$p1->setLabel("point #1");
print_r(get_object_vars($p1));

?>
上边的程序将输出:
Array
 (
     [x] => 1.233
     [y] => 3.445
     [label] =>
 )

 Array
 (
     [x] => 1.233
     [y] => 3.445
     [label] => point #1
 )

参见 get_class_methods()get_class_vars()


add a note add a note User Contributed Notes
armantic101 at gmail dot com
24-Aug-2006 10:01
I've been spoiled by OOP in C++ so I thought it was strange there was no built in copy constructor (At least not one that I could find ..sorry, I'm still kinda new to PHP).

I was able to use get_object_vars to simulate this. Here it is if anyone else can find it usefull.

<?php
class SomeObj {

 
private $myVar1 = 0;
 
private $myVar2 = 0;

 
# constructor
 
function SomeObj($_obj = Null) {
  
#check just to make sure ;-)
  
if (get_class($_obj) == get_class($this) ) {
    
$arMyVars = get_object_vars($_obj);
     foreach (
$arMyVars as $name => $value) {
      
$this->$name = $value;
     }
   }
  }

  function
changeVars($_var1, $_var2) {
  
$this->myVar1 = $_var1;
  
$this->myVar2 = $_var2;
  }

  function
printVars() {
   print
"$this->myVar1 $this->myVar2\n";
  }
}

$oldObj = new SomeObj();
$oldObj->printVars();
$oldObj->changeVars(1, 2);
$newObj = new SomeObj($oldObj);
$newObj->printVars();

?>

output:
0 0
1 2

Hope someone can find this usefull.

...now to figure out how to make multiple constrictors.
ananda dot putra at gmail dot com
01-Mar-2006 07:49
Hi all, I just wrote a function which dumps all the object propreties and its associations recursively into an array. Here it is..
<?php
function object_to_array($obj) {
      
$_arr = is_object($obj) ? get_object_vars($obj) : $obj;
       foreach (
$_arr as $key => $val) {
              
$val = (is_array($val) || is_object($val)) ? object_to_array($val) : $val;
              
$arr[$key] = $val;
       }
       return
$arr;
}
?>

Example:
You have an object like this:
fruitsbasket Object
(
   [Fruits] => Array
       (
           [0] => fruits Object
               (
                   [_name] => Mango
                   [_color] => Green
                   [_weight] => 10
               )

           [1] => fruits Object
               (
                   [_name] => Apple
                   [_color] => Red
                   [_weight] => 15
               )

           [2] => fruits Object
               (
                   [_name] => Grape
                   [_color] => Purple
                   [_weight] => 5
               )

       )

   [total_weight] => 30
)

just do:
<?php
$the_array
= object_to_array($the_object);
print_r($the_array);
?>

it will produce an array:
Array
(
   [Fruits] => Array
       (
           [0] => Array
               (
                   [_name] => Mango
                   [_color] => Green
                   [_weight] => 10
               )

           [1] => Array
               (
                   [_name] => Apple
                   [_color] => Red
                   [_weight] => 15
               )

           [2] => Array
               (
                   [_name] => Grape
                   [_color] => Purple
                   [_weight] => 5
               )

       )

   [total_weight] => 30
)

I wish function like this could be usefull for you all. :)
support at sascha minus diebel dot de
23-Dec-2005 06:55
Note that get_object_vars() returns the variables of the object not the class. You need to know if your class is extended from a parent class.
d11wtq (enquiries AT chriscorbyn.co.uk)
17-Nov-2005 07:40
Since there's no apparent means of obtaining all the *private* properties in an object I wrote a little function to do it.  Built in support would be much more efficient since mine uses a preg_  search to do this....

<?php

function get_private_properties($obj, $inside=false)
{
  
$obj_dump  = print_r($obj, 1);
  
preg_match_all('/^\s+\[(\w+):private\]/m', $obj_dump, $matches);
   if (
$inside)
   {
      
$output = array();
       foreach (
$matches[1] as $property)
       {
          
$output[$property] = $obj->$property;
           return
$output;
       }
   }
   else return
$matches[1];
}

?>

So if you run it with the optional second paramter missing you'll just get an array of the variable names that are private inside the class.  This is the only option if you are not inside the actual object and the object has no private properties inherited.

If you run it with the second parameter set to true you will get an associative array with the properties and their corresponding values.  I'd only advise to do that for singletons since you may get errors if there are any private properites in parents/children.
pascal dot poncet at netconsult dot com
13-Oct-2005 10:20
Subject: using "sql_calc_found_rows" in a MySQL query while exploiting result in a PHP db class object.

Hello,

There is a nice function in MySQL that allows to know how many records would have been returned if no "where" clause were set : SQL_CALC_FOUND_ROWS.

If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.

Why ?
Simply because the returned field's name is "found_rows()" and obviously it's not possible to call something like :

<?php $result->found_rows() ?>

...as it will try to acces a method, not a property !

Then, the only way to get the right result seems to be the use of a class function, like :

<?php
  $db
->query("select found_rows()");
 
$count=current(get_object_vars(current($db->result)));
?>

Of course, if somebody found an other way to solve it, like a special syntax (see the one used with curled arrays in a string), I'm really open to discuss.

Good luck,
Pascal
Marc
23-Aug-2005 09:08
If you want to access all properties (private, protected, public) of a class and his base class(es) from outside the object you can take a look in the code below.
You can even reffrence them.

Example:
<?php

// Dummy class to act as parent class.
class Dummy
{
  
private        $d1 = 1;
  
protected    $d2 = 2;
  
public        $d3 = 3;
}

// The class to test on.
class Test extends Dummy
{
  
private        $t1 = 11;
  
protected    $t2 = 12;
  
public        $t3 = 13;
}

// Instance of the test class.
$test =& new Test();

// The propertynames of the test class and his parent.
$nameD1 = "\0Dummy\0d1";    // class Dummy, private      $d1
$nameD2 = "\0*\0d2";        // class Dummy, protected $d2
$nameD3 = "d3";            // class Dummy, public    $d3

$nameT1 = "\0Test\0t1";        // class Test,  private      $t1
$nameT2 = "\0*\0t2";        // class Test,  protected $t2
$nameT3 = "t3";            // class Test,  public    $t3

// Printing all members (private, protected, public) of test class and parent.
// These are the values at construction.
print("Original object:\n");
print(
"\t\$d1 = ".$test->$nameD1."\n");
print(
"\t\$d2 = ".$test->$nameD2."\n");
print(
"\t\$d3 = ".$test->$nameD3."\n");
print(
"\t\$t1 = ".$test->$nameT1."\n");
print(
"\t\$t2 = ".$test->$nameT2."\n");
print(
"\t\$t3 = ".$test->$nameT3."\n");
print(
"\n");

// Create new values to use as reffrence.
$varD1 = 31;
$varD2 = 32;
$varD3 = 33;

$varT1 = 41;
$varT2 = 42;
$varT3 = 43;

// Reffrence these to the class properties.
$test->$nameD1 =& $varD1;
$test->$nameD2 =& $varD2;
$test->$nameD3 =& $varD3;

$test->$nameT1 =& $varT1;
$test->$nameT2 =& $varT2;
$test->$nameT3 =& $varT3;

// Printing all members (private, protected, public) of test class and parent.
// The values have changed by assigning reffrence to them.
print("Object Changed by reffrence (1):\n");
print(
"\t\$d1 = ".$test->$nameD1."\n");
print(
"\t\$d2 = ".$test->$nameD2."\n");
print(
"\t\$d3 = ".$test->$nameD3."\n");
print(
"\t\$t1 = ".$test->$nameT1."\n");
print(
"\t\$t2 = ".$test->$nameT2."\n");
print(
"\t\$t3 = ".$test->$nameT3."\n");
print(
"\n");

// Change the original values.
// This will change the class properties.
$varD1 = 61;
$varD1 = 62;
$varD1 = 63;

$varT1 = 71;
$varT1 = 72;
$varT1 = 73;

// Printing all members (private, protected, public) of test class and parent.
// The values have changed because the variables $varXX have been changed.
print("Object Changed by reffrence (2):\n");
print(
"\t\$d1 = ".$test->$nameD1."\n");
print(
"\t\$d2 = ".$test->$nameD2."\n");
print(
"\t\$d3 = ".$test->$nameD3."\n");
print(
"\t\$t1 = ".$test->$nameT1."\n");
print(
"\t\$t2 = ".$test->$nameT2."\n");
print(
"\t\$t3 = ".$test->$nameT3."\n");
print(
"\n");

// Printing the object using print_r() shows the changes
// have been done on the object.
print("Object Changed (print_r):\n");
print_r($test);
print(
"\n");

// If you dont now the class propertynames you can get these by casting the
// object to an array. The array keys are the names
$prop = array_keys((array) $test);
print(
"Getting all class propertynames (print_r)\n");
print_r($prop);

//Result
/*

Original object:
   $d1 = 1
   $d2 = 2
   $d3 = 3
   $t1 = 11
   $t2 = 12
   $t3 = 13

Object Changed by reffrence (1):
   $d1 = 31
   $d2 = 32
   $d3 = 33
   $t1 = 41
   $t2 = 42
   $t3 = 43

Object Changed by reffrence (2):
   $d1 = 63
   $d2 = 32
   $d3 = 33
   $t1 = 73
   $t2 = 42
   $t3 = 43

Object Changed (print_r):
Test Object
(
   [t1:private] => 73
   [t2:protected] => 42
   [t3] => 43
   [d1:private] => 63
   [d2:protected] => 32
   [d3] => 33
)

Getting all class propertynames (print_r)
Array
(
   [0] => Test

*/

?>
stachnik at gmail dot com
03-Aug-2005 12:00
In PHP5 to get an array with all properties (even the private ones) all you have to do is write a public method that returns an array for your class:

public function getArray()
{
  return get_object_vars($this);
}

and then

$myBeautifulArray = $myBeautifulObject->getArray ();

Have BEAUTIFUL day :)
fmmarzoa at librexpresion dot org
02-Nov-2004 03:53
You can still cast the object to an array to get all its members and see its visibility. Example:

<?php

class Potatoe {
  
public $skin;
  
protected $meat;
  
private $roots;

   function
__construct ( $s, $m, $r ) {
      
$this->skin = $s;
      
$this->meat = $m;
      
$this->roots = $r;
   }
}

$Obj = new Potatoe ( 1, 2, 3 );

echo
"<pre>\n";
echo
"Using get_object_vars:\n";

$vars = get_object_vars ( $Obj );
print_r ( $vars );

echo
"\n\nUsing array cast:\n";

$Arr = (array)$Obj;
print_r ( $Arr );

?>

This will returns:

Using get_object_vars:
Array
(
   [skin] => 1
)

Using array cast:
Array
(
   [skin] => 1
   [ * meat] => 2
   [ Potatoe roots] => 3
)

As you can see, you can obtain the visibility for each member from this cast. That which seems to be spaces into array keys are '\0' characters, so the general rule to parse keys seems to be:

Public members: member_name
Protected memebers: \0*\0member_name
Private members: \0Class_name\0member_name

I've wroten a obj2array function that creates entries without visibility for each key, so you can handle them into the array as it were within the object:

<?php

function obj2array ( &$Instance ) {
  
$clone = (array) $Instance;
  
$rtn = array ();
  
$rtn['___SOURCE_KEYS_'] = $clone;

   while ( list (
$key, $value) = each ($clone) ) {
      
$aux = explode ("\0", $key);
      
$newkey = $aux[count($aux)-1];
      
$rtn[$newkey] = &$rtn['___SOURCE_KEYS_'][$key];
   }

   return
$rtn;
}

?>

I've created also a <i>bless</i> function that works similar to Perl's bless, so you can further recast the array converting it in an object of an specific class:

<?php

function bless ( &$Instance, $Class ) {
   if ( ! (
is_array ($Instance) ) ) {
       return
NULL;
   }

  
// First get source keys if available
  
if ( isset ($Instance['___SOURCE_KEYS_'])) {
      
$Instance = $Instance['___SOURCE_KEYS_'];
   }

  
// Get serialization data from array
  
$serdata = serialize ( $Instance );

   list (
$array_params, $array_elems) = explode ('{', $serdata, 2);
   list (
$array_tag, $array_count) = explode (':', $array_params, 3 );
  
$serdata = "O:".strlen ($Class).":\"$Class\":$array_count:{".$array_elems;

  
$Instance = unserialize ( $serdata );
   return
$Instance;
}
?>

With these ones you can do things like:

<?php

define
("SFCMS_DIR", dirname(__FILE__)."/..");
require_once (
SFCMS_DIR."/Misc/bless.php");

class
Potatoe {
  
public $skin;
  
protected $meat;
  
private $roots;

   function
__construct ( $s, $m, $r ) {
      
$this->skin = $s;
      
$this->meat = $m;
      
$this->roots = $r;
   }

   function
PrintAll () {
       echo
"skin = ".$this->skin."\n";
       echo
"meat = ".$this->meat."\n";
       echo
"roots = ".$this->roots."\n";
   }
}

$Obj = new Potatoe ( 1, 2, 3 );

echo
"<pre>\n";
echo
"Using get_object_vars:\n";

$vars = get_object_vars ( $Obj );
print_r ( $vars );

echo
"\n\nUsing obj2array func:\n";

$Arr = obj2array($Obj);
print_r ( $Arr );

echo
"\n\nSetting all members to 0.\n";
$Arr['skin']=0;
$Arr['meat']=0;
$Arr['roots']=0;

echo
"Converting the array into an instance of the original class.\n";
bless ( $Arr, Potatoe );

if (
is_object ($Arr) ) {
   echo
"\$Arr is now an object.\n";
   if (
$Arr instanceof Potatoe ) {
       echo
"\$Arr is an instance of Potatoe class.\n";
   }
}

$Arr->PrintAll();

?>
27-Oct-2004 11:02
actually, it's not entirely true that php5 will only return public members....php5 will return any variable IT HAS ACCESS TO

In other words, if you do a get_class_variables($this) inside a class, you'll get everything - public, private, the whole shebang...really annoying since you can't check to see what's private/public without using reflection
fbn79 at libero dot it
06-Apr-2004 08:26
In PHP5 it return only public variables.
manicdepressive AT mindless DOT com
06-Mar-2004 11:57
more strange, strange behaviour:

if you are trying to deep-copy an object with get_object_vars(), strange behaviour can accidentally clobber your original object properties.  please read very, very carefully:

get_object_vars() may either return references to *or* deep copies of the object's properties *depending on whether that property has been set with the -> operator*.  (this behaviour probably varies per php platform and os so please confirm for yourself.)

furthermore, consider
  $properties = get_object_vars($obj);
normally, unset()ting a reference does not affect the original, i.e. $ref = NULL; is not the same as unset($ref); per the references documentation.  However, if you have this strange references version and you unset() an array element of $properties, it will *SET THE OBJECT PROPERTY TO NULL*, which is not how references normally work. 

even stranger behaviour comes into effect that i can only express with an example.  please test this with your version and OS and proceed very carefully:
-->
<?php
echo "<pre>\n";

class
Lump
{
   var
$size = 'average';

   function &
copy()
   { 
// return a deep copy
    
$copy = new Lump(); 
    
$properties = get_object_vars($this);
     foreach(
array_keys( $properties ) as $property ){
        
$copy->$property = $properties[$property];  // deep, right?
    
}
     return
$copy;
   }

}

$lump = new Lump();

$lump->size = 'huge'// <--- this line changes everything
// comment above line out, and see the difference
// also, try substituting another property for 'size'

$properties = get_object_vars($lump);
$properties['size'] = 'small'; // this behavior varies

echo "after changing the properties array:\n";
var_dump( $lump ); 
// it's either big or small (never huge) depending on
// whether you commented-out the indicated line

//------------- let's try using our copy() method

$original_lump = new Lump();
$original_lump->size = 'huge'; // this line changes the behaviour
$other_lump =& $original_lump->copy();
unset(
$other_lump->size );
echo
"after unsetting in copy:\n";
var_dump( $original_lump ); // i'm afraid so -- original value clobbered !

echo "</pre>\n";
?>
code till dawn,
   mark meves
christopher AT NOSPAM AT idealab DOT com
31-Dec-2003 07:12
Hmmm.  A bit embarassing...

It turns out the best way to get references to all of your objects member variables is NOT with the functions I provided before, or with get_object_vars.

Just cast the object to array.

$a=(array)$obj;

# The two following statements are now equivalent and identical
$a["member"]=3;
$obj->member=3;

A very powerful tool, for inspectors and what not.
christopher AT NOSPAM AT idealab DOT com
24-Dec-2003 04:49
Please note that you cannot affect the object via the array values...in other words, the returned array does not contain references to the values within the object, but copies.

If you are making an object inspector or editor, this is not good enough.  So I made the following methods:

METHODS:

function &getVar($obj, $name)
{
       $expr="\$prop=&\$obj->$name;";
       eval($expr);
       return $prop;
}

function &getObjectVars($obj)
{
       $result=array();
       $vars=get_object_vars($obj);
       foreach ($vars as $var => $value)
       {
               $result[$var]=&getVar(&$obj, $var);
       }
       return $result;
}

[NOTE:  You must pass in a reference to an object, not an object.  Sorry if this  offends PHP'ers, but the distinction of pass-by-value and copy-on-assignment drives me batty (compared to Python, Java, Smalltalk), so I make all my functions pass by value, and force myself to pass in a reference to keep track of what is happening under the hood.]

EXAMPLE:

class Bob
{
       function Bob()
       {
               $this->thing=13;
               $this->other="whatever";
       }

       var $thing;
       var $other;
}

$obj=&new Bob();

# NOTE:  Passing in a reference!
$props=getObjectVars(&$obj);
$props["thing"]=-11;

var_dump($obj);

RESULTS:

object(bob)(2) {
  ["thing"]=>
  &int(-11)
  ["other"]=>
  &string(8) "whatever"
}
jordi at laigu dot net
06-Nov-2003 09:21
In case your object contains again OBJECTS or ARRAYS:

function makeAssoc($res) {
  if (is_object($res)) $res = get_object_vars($res);
  while (list($key, $value) = each($res)) {
   if (is_object($value) || is_array($value)) {
     $res[$key] = makeAssoc($value);
   }
  }
  return $res;
}

Thanks to mark at dreamzpace dot com
markus at emedia-solutions-wolf dot de
07-Mar-2003 04:01
Hi,

I figured out that in prior version to 4.2 the returned array only contains attributes directly in this class, excluding the derived ones from parentclasses.
info at phpken dot de
22-Nov-2002 10:34
hello,

this example will look like all values of vars was set in your class. write a method like the name: dumpClass and then fill in follow code:

$vars = get_object_vars($this);

echo "<b>class vars</b>";

foreach( $vars as $name => $value ) {
   echo "<li>".$name." : ".$value;
}

look at: get_object_vars($this);

andreas v.l
mark at dreamzpace dot com
14-Sep-2002 01:44
In case your object contains again objects (and so on), this function might be useful:

function makeAssoc($res) {
  $res = get_object_vars($res);
  while (list($key, $value) = each($res)) {
   if (is_object($value)) {
     $res[$key] = makeAssoc($value);
   }
  }
  return $res;
}
nick_eby at bonzidev dot com
10-Jul-2002 03:13
Furthermore, variables not declared in the class but set on a given object, will be returned by get_object_vars().

Example, ver. 4.2.1:
<?
class MyTest {
       var
$classVar1 = 'Class Var 1';
       var
$classVar2;
       var
$classVar3;

       function
MyTest()
       {
              
$this->classVar2 = 'class var 2';
       }
}

$test = new MyTest();
// This var isn't declared in the class
$test->newObjVar = 'foobar';

echo
"<pre>";
print_r(get_object_vars($test));
echo
"</pre>";
?>

The output is:
Array
(

   [classVar1] => Class Var 1
   [classVar2] => class var 2
   [classVar3] =>
   [newObjVar] => foobar
)

Prior to version 4.2, classVar3 would not be output as it was never assigned a value.
michael at tapinternet dot com
14-Jun-2002 06:32
It seems that get_object_vars will now return properties of an object even if they have no value  - meaning only defined by var $foo in the class declaration.  This is noted behaviour in 4.2.1 which is different from previous versions and hitherto undocumented on this page.
florian at XCLUDETHISgsf dot de
30-Jan-2002 02:02
There is a strange behaviour, not sure whether it is a bug:

if I call
<?
$single_object
= $data_array_of_objects[0];
$array_of_objectvars = get_object_vars($single_object);
     foreach(
$array_of_objectvars as $key => $val) {
     echo(
" $key => $val<br>");
     }
?>
I get only _ONE_ line with the $key = first variable name of the object and $val = the values of _ALL_ variables of the object including the first separated by a space.

NOW:
if I call
<?
$single_object
= $data_array_of_objects[0];
$array_of_objectvars = get_object_vars($single_object);
     foreach(
$array_of_objectvars as $key => $val) {
     echo(
" $key => $val<br>");
     }
     echo(
$data_array_of_objects[0]->objectvar1."<br>");
     echo(
$data_array_of_objects[0]->objectvar2."<br>");
?>

I get a list of $key = $ val as expected, before the other echos' are printed.
It seems to me that get_object_vars works differently when you access a variable in those objects explicitly (as in the echos)