Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Language Reference : Types : Objects

Objects

Object Initialization

To initialize an object, you use the new statement to instantiate the object to a variable.

<?php
class foo
{
function
do_foo()
{
echo
"Doing foo.";
}
}

$bar = new foo;
$bar->do_foo();
?>

For a full discussion, please read the section Classes and Objects.

Converting to object

If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instance of the stdClass built in class is created. If the value was NULL, the new instance will be empty. Array converts to an object with properties named by array keys and with corresponding values. For any other value, a member variable named scalar will contain the value.

<?php
$obj
= (object) 'ciao';
echo
$obj->scalar; // outputs 'ciao'
?>

Related Examples ( Source code ) » language.types.object





Code Examples / Notes » language.types.object

trevor blackbird > yurab.com

You can create a new object using the built-in stdClass or by using type-casting:
<?php
// This is the proper way
$object1 = new stdClass();
// This works too
$object2 = (object) NULL;
// This will create an object from an array
$monkey_array = array('title'=>'Spider Monkey', 'src'=>'monkey.jpg');
$monkey_object = (object) $monkey_array;
print $monkey_object->title . ' ' . $monkey_object->src;
// You can type-cast in the middle of an expression
function customHTML($some_object) {
// this function expects an object as the argument and returns some output
}
print '

Writing some output ' . customHTML( (object) array('rows'=>3, 'cols'=>4) );
?>


iblun

To sort an array, that contains an object, after one fieldname inside the object, im using this function:
function objectSort($objectarray, $field)
{
for ($a=0;$a < (count($objectarray)); $a++)
{
for ($b=0;$b < (count($objectarray)); $b++)
{
if ($objectarray[$a]->$field < $objectarray[$b]->$field)
{
$temp = $objectarray[$a];
$objectarray[$a] = $objectarray[$b];
$objectarray[$b] = $temp;
}
}
}

return $objectarray;
}


info

PHP supports recursive type definitions as far as I've tried. The class below (a _very_ simple tree) is an example:
class Tree {
var $_value = null;
var $_children = array();
function Tree ($value) {
 $this->_value = $value;
}
function addChild ($value) {
 $aux_node = new Tree ($value);
 $this->_children [] = $aux_node;
 return $aux_node;
}
}
As you can see, in addChild we reference Tree again...
However, you must be careful about references. See the chapter "References explained" for more details.
Hope this helps.


nconantj

php at electricsurfer.com,
More than a year later and here's some clarification of what's happening in your code, via comments in an otherwise verbatim copy.
<?
class c
{
  var $a = array('a'=>'aa','b'=>'ab');
  var $b = 'c';
 
  function show()
  {
      echo $this->a['a']; // -> 1st
      echo $this->a['b']; // outputs 'ab'
     
      $a = 'a';
      $b = 'b';
     
      echo $this->$a[$a]; // [] 1st, not what I expected
      //Above first becomes $this->$a['a'] by looking at the function's local $a
      //Next it becomes $this->a by again looking at the function's local $a, which references the class variable $a with no subscripts.
      // In order to reference elements of the class variable $a,
      // you want to use $this->a[$a]
      echo $this->$a[$b]; // does NOT output 'ab'
      // Same as above, but the first step $b becomes 'b'
      $this_a =& $this->$a; // work-around
     
      echo $this_a[$a]; // no question
      echo $this_a[$b];
     
      $a_arr = array('a'=>'b');
     
      echo $this->$a_arr[$a]; // [] 1st => outputs 'c'
      // This becomes $this->$a_arr['a'] which becomes $this->c,
      // by referencing the local variables first.
  }
}
$c = new c();
$c->show();
?>


gabe

In response to sirbinam.
You cannot call a function or method before it exists. In your example, the global instance of stdout is just being passed around to differnet references (pointers). It however exists in the "dump" function scope via the global keyword.
The code below works fine and illustrates that "stdout" has been defined before its instantiation.
<?php
class profiler{
 function profiler(){
   $this->starttime = microtime();
 }
 function dump(){
   global $stdout;
   $this->endtime = microtime();
   $duration = $this->endtime - $this->starttime;
   $stdout->write($duration);
 }
}
class stdout{
 function write($msg){
   echo $msg;
 }
}
$stdout =& new stdout();
$profiler =& new profiler();
$profiler->dump();
?>
All classes and functions declarations within a scope exist even before the php execution reaches them. It does not matter if you have your classes defined on the first or last line, as long as they are in the same scope as where they are called and are not in a conditional statement that has not been evaluated yet.


ludvig dot ericson

In reply to the usort thing, you can access a property of an object dynamically by:
<?php
$obj = (object)array("Test" => "bar")
$var = "Test";
echo $obj->$var;
?>
This will output "bar", and do notice I call on ->$var and not just ->var.


mortoray

If you use new to create items in an array, you may not get the results you want since the parameters to array will be copies of the original and not references.
By Example:
class Store {
   var $item = 3;
}
   $a = array( new Store() );
   $b = $a;
   $a[0]->item = 2;
   print( "|" . $b[0]->item . "|
" );   //shows 3
   $a = array();
   $a[] =& new Store();
   $b = $a;
   $a[0]->item = 2;
   print( "|" . $b[0]->item . "|
" );   //shows 2
This is extremely important if you intend on passing arrays of classes to functions and expect them to always use the same object instance!
Note: The following syntax is desired (or maybe even the default notation should translate as this):
  $a = array( &new Store() );


james dot jones

iblun:
Highly recommended that you NOT try to write your own sort function. Try something like this instead:
<?php
function sort_by_field($obj_array, $field)
{
  return usort($obj_array,
        create_function('$o1,$o2',
             "return (\$o1->$field < \$o2->$field) ? -1 : 1"));
}
?>
(Warning: untested code...)


php

Here's an example on operator precedence between ->  and []
& what happens with $object->$member[$array_element]
<?
class c
{
var $a = array('a'=>'aa','b'=>'ab');
var $b = 'c';

function show()
{
echo $this->a['a']; // -> 1st
echo $this->a['b']; // outputs 'ab'

$a = 'a';
$b = 'b';

echo $this->$a[$a]; // [] 1st, not what I expected
echo $this->$a[$b]; // does NOT output 'ab'

$this_a =& $this->$a; // work-around

echo $this_a[$a]; // no question
echo $this_a[$b];

$a_arr = array('a'=>'b');

echo $this->$a_arr[$a]; // [] 1st => outputs 'c'
}
}
$c = new c();
$c->show();
?>


sirbinam

<?php
class hack{}
$hack =& new hack;
class profiler{
 function profiler(){
   $this->startime = microtime();
 }
 function dump(){
   global $hack;
   $this->endtime = microtime();
   $duration = $this->endtime - $this->starttime; /* this won't actually work, it just the concept */
   $stdout->write($duration);
 }
}
class stdout{
 function write($msg){
   echo $msg;
 }
}
$stdout =& new stdout();
$hack =& $stdout;
$profiler->dump();
?>
/*
    *
    * In short this little hack allows us to call $stdout->write() from
    * $profiler->dump
    *
    * The problem is that $stdout doesn't exist yet and when the compiler
    * parses this class, it sends a fatal error and dies because you can't
    * refer to a method of an object that doesn't exist yet, even though
    * this method doesn't get called until the end of execution, when the
    * method does exist.
    * This is the same as not being able to use a function before it is
    * at least declared in say a header file. This is seen in C, Perl,
    * and pretty much every language known to man. (TTBOMK?)
    *
    * So what does this hack do?
    * The first thing that happens in the global scope is an empty class
    * definition, it then creates a object called $hack from this class.
    * All this does is allocate memory for an object, and places a pointer
    * at the begining of that memory segment.
    * When the compiler parses this class, it doesn't care that the $hack
    * object is empty, as long as it has somewhere to assign a function
    * pointer. Later in global scope the $stdout object is created.
    * After $stdout is created, we do $hack =& $stdout. The =&
    * (assign by reference) moves the pointer for $hack to the begining of
    * the memory segment for $stdout. So when we call $hack->write(), it
    * points to the exact same object->method() as $stdout->write(). So
    * this is actually very reliable, just don't tell a purist!
    */


jbinam

<?php
class hack{}
$hack =& new hack;
class profiler{
 function profiler(){
   $this->startime = microtime();
 }
 function dump(){
   global $hack;
   $this->endtime = microtime();
   $duration = $this->endtime - $this->starttime; /* this won't actually work, it just the concept */
   $stdout->write($duration);
 }
}
class stdout{
 function write($msg){
   echo $msg;
 }
}
$stdout =& new stdout();
$hack =& $stdout;
$profiler->dump();
?>
/*
    *
    * In short this little hack allows us to call $stdout->write() from
    * $profiler->dump
    *
    * The problem is that $stdout doesn't exist yet and when the compiler
    * parses this class, it sends a fatal error and dies because you can't
    * refer to a method of an object that doesn't exist yet, even though
    * this method doesn't get called until the end of execution, when the
    * method does exist.
    * This is the same as not being able to use a function before it is
    * at least declared in say a header file. This is seen in C, Perl,
    * and pretty much every language known to man. (TTBOMK?)
    *
    * So what does this hack do?
    * The first thing that happens in the global scope is an empty class
    * definition, it then creates a object called $hack from this class.
    * All this does is allocate memory for an object, and places a pointer
    * at the begining of that memory segment.
    * When the compiler parses this class, it doesn't care that the $hack
    * object is empty, as long as it has somewhere to assign a function
    * pointer. Later in global scope the $stdout object is created.
    * After $stdout is created, we do $hack =& $stdout. The =&
    * (assign by reference) moves the pointer for $hack to the begining of
    * the memory segment for $stdout. So when we call $hack->write(), it
    * points to the exact same object->method() as $stdout->write(). So
    * this is actually very reliable, just don't tell a purist!
    */


Change Language


Follow Navioo On Twitter
Introduction
Booleans
Integers
Floating point numbers
Strings
Arrays
Objects
Resource
NULL
Pseudo-types and variables used in this documentation
Type Juggling
eXTReMe Tracker