Here is a working code with a static method. It also uses the fact that the static method can access private ivars :) It also uses PHP awesome reflexivity <3.
The good point about that code is that Person is the class to provide the sort method, which is better on an OOP point of view. Only the class Person should be the one to know how to sort other Person. Neither People or another indepent function should.
Note: not using is_callable(), as it only verifies if the parameter can be called as a function, but does not check if it's actually callable with the current visibility (public, private, protected)
class Person { private $name, $sex, $age; public function Person($name, $sex, $age) { $this->name = $name; $this->sex = $sex; $this->age = $age; }
public static function sortByName(Person $p1, Person $p2)
{
return strcmp($p1->name, $p2->name);
}
public static function sortByAge(Person $p1, Person $p2)
{
return ($p1->age - $p2->age);
}
}
class People { private $people = array(); public function addPerson($name, $sex, $age) { $this->people[] = new Person($name, $sex, $age); }
public function display()
{
print_r($this->people);
}
public function sort($attribute = 'name')
{
$sortFct = 'sortBy' . ucfirst(strtolower($attribute));
if (!in_array($sortFct, get_class_methods('Person')))
{
throw new Exception('People->sort(): Can\\'t sort by ' . $attribute);
}
usort($this->people, 'Person::' . $sortFct);
}
}
$people = new People; $people->addPerson('Steve', 'M', 31); $people->addPerson('John', 'M', 24); $people->addPerson('Jane', 'F', 26); $people->addPerson('Sally', 'F', 21); $people->display(); $people->sort(); $people->display(); $people->sort('age'); $people->display();
…
Take a look at usort. It allows you to specify your own comparison function. Every time two objects need to be compared, it will call that comparison function you specify to see which one is greater than the other (or if they are equal). In your comparison function you can do whatever you need to with the fields in the two Person objects to compare them.
For doing callbacks with class methods (as in your example), look at passing callbacks. For example, you could do something like this:
class People { // your previously defined stuff here...
public function sort() {
usort($this->people, array($this, 'comparePeople'));
}
public function comparePeople(Person $p1, Person $p2) {
return strcmp($p1->getName(), $p2->getName());
}
}
You would also of course need to add getName() to your Person class.
For a static approach, it might look something like this:
function sortPeople($people) { usort($people, array('People', 'comparePeople')); }
class People { // your previously defined stuff here...
public static function comparePeople(Person $p1, Person $p2) {
return strcmp($p1->getName(), $p2->getName());
}
}
As you can see, it looks very similar. I would not recommend you use the static approach. It's messier and violates the single responsibility principle.
[http://stackoverflow.com/questions/1528561/ how-to-sort-an-array-of-objects-in-php]