5

I want to sort the properties of an object so I can loop through them in a defined order.

for example: I have an object 'book' with the following properties: 'id', 'title', 'author', 'date'.

Now i want to loop through these properties like this:

foreach($book as $prop=>$val)
//do something

now the order of the loop has to be 'title', then 'author', 'date' and 'id'

How would one do this? (I can't change the order of the properties in the class of the object because there arent any properties defined there, I get the object from the database with 'MyActiveRecord')

3 Answers 3

8

Not sure if this answers to your question, but you could try :

$properties = array('title', 'author', 'date', 'id');
foreach ($properties as $prop) {
    echo $book->$prop;
}

Alternatively, you could extract the properties of the book (instead of hardcoding them), and sort them with your custom order :

$props = get_class_vars(get_class($book));
uasort($props, 'my_properties_sorting_function');
Sign up to request clarification or add additional context in comments.

1 Comment

Ok thx, I went for the array of properties and looping through them, seems the simplest answer to me ;)
4

You could wrap your source object into something that implements the Iterator interface and returns the properties of the source object in a given sort order.

class Foo implements Iterator {
  protected $src;
  protected $order;
  protected $valid;

  public function __construct(/*object*/ $source, array $sortorder) {
    $this->src = $source;
    $this->order = $sortorder;
    $this->valid = !empty($this->order);
  }
  public function current() { return $this->src->{current($this->order)}; }
  public function key() { return key($this->order); }
  public function next() { $this->valid = false!==next($this->order); }
  public function rewind() { reset($this->order); $this->valid = !empty($this->order); }

  public function valid() { return $this->valid; }
}

class Book {
  public $id='idval';
  public $author='authorval';
  public $date='dateval';
  public $title='titleval';
}


function doSomething($it) {
  foreach($it as $p) {  
    echo '  ', $p, "\n";
  }
}

$book = new Book;
echo "passing \$book to doSomething: \n";
doSomething($book);

$it = new Foo($book, array('title', 'author', 'date', 'id'));
echo "passing \$it to doSomething: \n";
doSomething($it);

prints

passing $book to doSomething: 
  idval
  authorval
  dateval
  titleval
passing $it to doSomething: 
  titleval
  authorval
  dateval
  idval

2 Comments

much more complicated than my answer, but much more object-oriented, smart and reusable. +1
and also slower than your version. The SPL isn't the fastest gun in all PHP land ;-)
3

Try this. The difference between this method and the method proposed in the first response is that the method get_class_vars returns default properties of the class, whereas get_object_vars returns the properties of the given object.

<?php

class Book {
  public $title;
  public $author;
  public $date;
  public $id;
}

  $b = new Book();
  $b->title = "title";

  $object_vars = get_object_vars($b);
  ksort($object_vars);

  foreach($object_vars as $prop=>$val)
        echo $prop."->".$val."<br>";

?>

1 Comment

This does not achieve the requested order.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.