Complex Sorting with PHP

Most often when I need to sort complex data sets, I'm using some sort of SQL backend. Today I needed to do complex sorting of Reflection objects for some auto generating documentation I'm working on for the upcoming Picora release. Namely, I needed to sort methods according to the following criteria:

  • is static
  • visibility
  • alphabetical order

In the usort() examples, I had always been under the assumption (and from other folks code, I know I'm not the only one) that the return values had to be 0, 1 or -1.

Today I learned that is not true at all, and you can come up with your own scoring system with any range, negative or positive. A truncated, but fully functional example:

class PicoraDocumentationClass extends ReflectionClass {
    public function getMethods(){
        $methods = array();
        foreach(parent::getMethods() as $method)
            $methods[] = $this->getMethod($method->name);
        usort($methods,array('PicoraDocumentationClass','sort'));
        return $methods;
    }
    static public function sort($a,$b){
        $a_score = self::scoreFromMethod($a);
        $b_score = self::scoreFromMethod($b);
        return ($a_score == $b_score) ? 0 : ($a_score < $b_score ? -1 : 1);
    }
    static protected function scoreFromMethod(PicoraDocumentationMethod $m){
        return array_sum(array(
            ($m->isStatic() ? -100000 : 0),
            ($m->isPublic() ? -10000 : 0),
            ($m->isProtected() ? -1000 : 0),
            ($m->isPrivate() ? -100 : 0),
            ord(substr($m->name,0,1))
        ));
    }
}

The PicoraController class methods when sorted appear would appear in this order:

  • static public flash
  • static public getFlash
  • static public render
  • static protected redirect
  • static protected renderRSS
  • static protected renderJSON
  • static protected sendFile
  • public afterCall
  • public beforeCall

Just as a quick side note, I'm not sure that scoring in orders of magnitude (100,1000,etc) was entirely nessecary, but it did do the trick right, and consistently. Also note PicoraDocumentationMethod is just a subclass of ReflectionMethod, all of those methods being called are in the Reflection engine.

Coming soon to a Picora project page near you...

Posted June 27th, 2007 at 7:31 pm by Ryan in Programming

Replies to this Post

Posted September 29th, 2007 at 8:03am by

Posted October 21st, 2007 at 5:33am by

Login or Register to Post