jump to navigation

Using Array-syntax to Access PHP-object Values January 24, 2013

Posted by Tournas Dimitrios in PHP.
trackback

Since PHP 5 we can “cast” an object to an array and use array-like syntax to manipulate its content . This works fine on simple data-structures . However , often we write object-oriented code in which data isn’t necessarily represented as simple key/values (one dimension array) , but by more complex data structures  (ie hierarchical data — multi-dimensional arrays–) . Just casting an Object , which contains complex data structures , to an array won’t  lead to the desired results . The following code demonstrates my earlier definition :

<?php
/**
 * Created by Tournasdimitrios.
 * Date: 1/24/13
 * Time: 21:26 PM
 */
class TestCasting
{
    public $pubArray = array(
                'pubArray-one' ,
                'pubArray-two' ,
                'pubArray-three' ,
        array(
                'pubArray-nested-one',
                'pubArray-nested-two')) ;
    private $_privArray = array(
                'privArray-one' ,
                'privArray-two' ,
                'privArray-three') ;
    protected $_protArray = array(
                'protArray-one' ,
                'protArray-two' ,
                'protArray-three') ;
    public $pubVar = 'Content of Public variable' ;
    private $_privVar = 'Another value' ;
    protected $_protVar = "xyz" ;

    public function __construct()
    {
    echo 'Class', __CLASS__ . " is instantiated" ;
    }
    public function castToArray() {
    return get_object_vars($this) ;
    }

}

$casting = new TestCasting() ;
$results = (array) $casting ;
echo '<pre>' ;
print_r($results) ;

echo '<h3>Looping the results</h3>' ;
foreach($results as $k => $v) {
    if(is_array($v)){
        foreach($v as $kNested => $vNested){
          if(is_array($vNested))  continue ;
         echo '-----', $kNested , 'has value of  : ', $vNested , '<br>';
        } // End of inner loop
    } else {
        echo $k , 'has value of :' , $v , '<br>' ;

    } // End of if-statement
} // End of Outer loop
echo 'Public variable : ' , $results['pubVar'] , '<br>' ;

/*
 * Result on Browser
ClassTestCasting is instantiated
Array
(
    [pubArray] => Array
        (
            [0] => pubArray-one
            [1] => pubArray-two
            [2] => pubArray-three
            [3] => Array
                (
                    [0] => pubArray-nested-one
                    [1] => pubArray-nested-two
                )

        )

    [TestCasting_privArray] => Array
        (
            [0] => privArray-one
            [1] => privArray-two
            [2] => privArray-three
        )

    [*_protArray] => Array
        (
            [0] => protArray-one
            [1] => protArray-two
            [2] => protArray-three
        )

    [pubVar] => Content of Public variable
    [TestCasting_privVar] => Another value
    [*_protVar] => xyz
)
Looping the results

-----0has value of  : pubArray-one
-----1has value of  : pubArray-two
-----2has value of  : pubArray-three
-----0has value of  : privArray-one
-----1has value of  : privArray-two
-----2has value of  : privArray-three
-----0has value of  : protArray-one
-----1has value of  : protArray-two
-----2has value of  : protArray-three
pubVarhas value of :Content of Public variable
TestCasting_privVarhas value of :Another value
*_protVarhas value of :xyz
Public variable : Content of Public variable
 */

As seen on the results , casting an object (to an array) has some important gotchas :

  • The member-names of the object (properties , methods) are represented by the keys on the resulting array
  •  private variables have the class name prepended to the variable name and protected variables have a ‘*‘ prepended to the variable name .
  • data of private and protected “members” are not accessible .

One could implement variety of solutions , all depends on the desired result . For instance , do we want to reach only publicly accessible components of the instantiated Class (object) , or do we need accessibility to all components (public , private and protected) . The following code demonstrates both scenarios .

Accessing all components (public , private and protected)   :

<?php
/**
 * Created by Tournasdimitrios.
 * Date: 1/24/13
 * Time: 21:41 PM
 */
class TestCasting
{
    public $pubArray = array(
                'pubArray-one' ,
                'pubArray-two' ,
                'pubArray-three' ,
        array(
                'pubArray-nested-one',
                'pubArray-nested-two')) ;
    private $_privArray = array(
                'privArray-one' ,
                'privArray-two' ,
                'privArray-three') ;
    protected $_protArray = array(
                'protArray-one' ,
                'protArray-two' ,
                'protArray-three') ;
    public $pubVar = 'Content of Public variable' ;
    private $_privVar = 'Another value' ;
    protected $_protVar = "xyz" ;

    public function __construct()
    {
    echo 'Class', __CLASS__ . " is instantiated" ;
    }
    public function castToArray() {
    return get_object_vars($this) ;
    }

}

$casted = new TestCasting() ;
$results2 = $casted->castToArray() ;
echo $results2['_protVar'],'<br>' ;
echo $results2['pubArray'][3][0] , '
';
echo '<h3>Looping only through first level values</h3>' ;
foreach($results2 as $k => $v) {
    if(is_array($v)){
    foreach($v as $kNested => $vNested){
    if(is_array($vNested))  continue ;
    echo '-----', $kNested , 'has value of  : ', $vNested , '<br>';
        } // End of inner loop
    } else {
    echo $k , 'has value of :' , $v , '<br>' ;

    } // End of if-statement
} // End of Outer loop

/*
 * Result on Browser
 ClassTestCasting is instantiated
xyz
pubArray-nested-one
Looping only through first level values

-----0has value of : pubArray-one
-----1has value of : pubArray-two
-----2has value of : pubArray-three
-----0has value of : privArray-one
-----1has value of : privArray-two
-----2has value of : privArray-three
-----0has value of : protArray-one
-----1has value of : protArray-two
-----2has value of : protArray-three
pubVarhas value of :Content of Public variable
_privVarhas value of :Another value
_protVarhas value of :xyz
 */

Accessing only public components :

<?php
/**
 * Created by Tournasdimitrios.
 * Date: 1/24/13
 * Time: 21:51 PM
 */
class TestCasting
{
    public $pubArray = array(
                'pubArray-one' ,
                'pubArray-two' ,
                'pubArray-three' ,
        array(
                'pubArray-nested-one',
                'pubArray-nested-two')) ;
    private $_privArray = array(
                'privArray-one' ,
                'privArray-two' ,
                'privArray-three') ;
    protected $_protArray = array(
                'protArray-one' ,
                'protArray-two' ,
                'protArray-three') ;
    public $pubVar = 'Content of Public variable' ;
    private $_privVar = 'Another value' ;
    protected $_protVar = "xyz" ;

    public function __construct()
    {
    echo 'Class', __CLASS__ . " is instantiated" ;
    }
    public function castToArray() {
    return get_object_vars($this) ;
    }

}
$casted = new TestCasting() ;
//$results2 = $casted->castToArray() ;
echo '<pre>' ;
$results2 = get_object_vars($casted) ;
print_r($results2) ;
echo '<h3>Looping only through first level values</h3>' ;
foreach($results2 as $k => $v) {
    if(is_array($v)){
        foreach($v as $kNested => $vNested){
            if(is_array($vNested))  continue ;
            echo '-----', $kNested , 'has value of  : ', $vNested , '<br>';
        } // End of inner loop
    } else {
        echo $k , 'has value of :' , $v , '<br>' ;

    } // End of if-statement
} // End of Outer loop

/*
 * Result on Browser
 ClassTestCasting is instantiated
Array
(
    [pubArray] => Array
        (
            [0] => pubArray-one
            [1] => pubArray-two
            [2] => pubArray-three
            [3] => Array
                (
                    [0] => pubArray-nested-one
                    [1] => pubArray-nested-two
                )

        )

    [pubVar] => Content of Public variable
)
Looping only through first level values

-----0has value of  : pubArray-one
-----1has value of  : pubArray-two
-----2has value of  : pubArray-three
pubVarhas value of :Content of Public variable
 */

These are not the only solutions , one could use SPL’s build-in array manipulation Classes (or Interfaces) , but that’s a subject for a future article . Stay tuned 🙂

Advertisements

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s