SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Nested Objects to Associative Array - Without Recursion

    Right,

    Here's one for you.

    Let's say I have these 3 classes.

    PHP Code:
    abstract class Model
    {
      public function 
    toArray(){
        
    $array = array();
        
    /*
          Do stuff, here.
        */
        
    return $array;
      }

    PHP Code:
    class RouteCollection extends Model
    {
      public
        
    $routes = array();

    PHP Code:
    class Route extends Model
    {
      protected
        
    $username 'anthonysterling',
        
    $password '5up3rS3cre7P@s5';
        
      public
        
    $url      '';

    Given the following usage...

    PHP Code:
    $routes = new RouteCollection;

    $routes->routes[0] = new Route;
    $routes->routes[0]->url 'Google Inc';

    $routes->routes[1] = new Route;
    $routes->routes[1]->url 'Yahoo Inc';
    $routes->routes[1]->cfg = new stdClass;
    $routes->routes[1]->cfg->public true;

    var_dump(
      
    $routes->toArray()
    ); 
    I'd like to see the following associative array created...

    PHP Code:
    /*
      array(
        'routes'  => array(
          0 => array(
            'username' => 'anthonysterling',
            'password' => '5up3rS3cre7P@s5',
            'url'      => 'Google Inc'
          ),
          1 => array(
            'username' => 'anthonysterling',
            'password' => '5up3rS3cre7P@s5',
            'url'      => 'Yahoo Inc',
            'cfg'      => array(
              'public'  => true
            )
          )
        )
      )
    */ 
    The gotchas? No recursion allowed, unlimited depth, not all nested objects are routes and some of the required properties are not public. The ->toArray method could be called on any object which extends Model and it should return the tree from that point forward.

    I'd love to see some SPL usage, as to provide a standard approach but I cannot see how this is possible due to the non-public properties - reflection appears to be out too for the very same reason (at least on < 5.3.0).

    So, shoot!
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  2. #2
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I scared you with too much code didn't I ?
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  3. #3
    SitePoint Addict
    Join Date
    Apr 2009
    Posts
    248
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    I scared you with too much code didn't I ?
    Why the requirement for no recursion? That seems like it would be the best way to do things.

  4. #4
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I don't like the idea of it.

    I can do it with recursion, but it still seems messy to me. Iteration, that's the name of the game.

    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  5. #5
    SitePoint Wizard
    Join Date
    Nov 2005
    Posts
    1,191
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    I don't like the idea of it.

    I can do it with recursion, but it still seems messy to me. Iteration, that's the name of the game.

    What can be done recursively can be done iteratively, but I think this will make a mess of code in PHP due to no proper pointers. Did you get anything working? I had a quick go, but gave up pretty quickly :|

  6. #6
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Heh, not really. I had a little play with an internal stack and an endless while loop which I broke out of one no more 'children' were present, but it was awfully messy.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  7. #7
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    No idea really...

    Code PHP:
    <?php
     
    class Tester
    {
        protected $username, $password, $special;
        public function __construct ( $username, $password ) {
            $this->username = $username;
            $this->password = $password;
        }
     
        public function addSpecial ( Tester $special ) {
            $this->special = $special;
            return $this;
        }
     
        public function toArray ()
        {
            $ret = array();
            foreach ( (array)$this as $prop => $value ) {
                $prop = trim( $prop, "\0*" ); // For Protected properties.
     
                if ( empty( $value ) ) continue;
     
                if ( is_object( $value ) ) {
                    $ret[ $prop ] = $value->toArray();
                    continue;
                }
     
                $ret[ $prop ] = $value;
            }
     
            return $ret;
        }
    }
     
    $t = new Tester( "Logic", "Fake" );
        $t->addSpecial( new Tester( "Frank", "Bob" ) );
    var_dump( $t->toArray() );
     
    /*
    array(3) {
      ["username"]=>
      string(5) "Logic"
      ["password"]=>
      string(4) "Fake"
      ["special"]=>
      array(2) {
        ["username"]=>
        string(5) "Frank"
        ["password"]=>
        string(3) "Bob"
      }
    }
    */
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  8. #8
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    The stdClass doesn't have a toArray() method.

    PHP Code:
    $routes->routes[1]->cfg = new stdClass;
    $routes->routes[1]->cfg->public true
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  9. #9
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    The stdClass doesn't have a toArray() method.

    PHP Code:
    $routes->routes[1]->cfg = new stdClass;
    $routes->routes[1]->cfg->public true
    Then you only need (array)$...

    PHP Code:
    if ( $value instanceof YourSpecialClass ) {
        
    $value->toArray();
        continue;
    }

    if ( 
    is_object$value ) ) (array)$value
    Something to that effect.
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  10. #10
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    But what about the stdClass' children? Those won't be iterated...
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  11. #11
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    Well then you are going have to use something other then stdClass otherwise it will just get messier and messier. :P PHP does have its limits.

    Or...use recursion.
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  12. #12
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by logic_earth View Post
    Or...use recursion.
    Ha.

    I refuse to be beaten, although I admit, recursion is (at least currently) the more cleaner option.

    Still, I'll hack away....

    Thanks!
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •