1

I'm having a problem with sorting items in a PHP class that extends ArrayObject.

I am creating my classes, and the only way I've figured out to add the cmp() function is to put it in the same file, but outside of the class. I can't seem to put it anyplace else because of the way uasort requires the function name as a string.

So I'm doing this:

class Test extends ArrayObject{

    public function __construct(){
        $this[] = array( 'test' => 'b' );
        $this[] = array( 'test' => 'a' );
        $this[] = array( 'test' => 'd' );
        $this[] = array( 'test' => 'c' );
    }


    public function sort(){
        $this->uasort('cmp');
    }

}

function cmp($a, $b) {
    if ($a['test'] == $b['test']) {
        return 0;
    } else {
        return $a['test'] < $b['test'] ? -1 : 1;
    }
}

Which is fine if I'm only using one class like this, but if I use two (either by autoloading or require) then it breaks on trying to invoke cmp() twice.

I guess my point is it just seems like a bad way to do this. Is there any other way I can keep the cmp() function inside the class itself?

2
  • I know I could call them different things but that seems like not such a great solution either. Commented May 29, 2015 at 16:17
  • Create a util.php file that contains this function and other similar utility function. Then require_once('util.php'); when you need it. Commented May 29, 2015 at 16:20

2 Answers 2

4

You could just do this, instead of calling a function just make it an anonymous function.

PHP 5.3.0 or higher only

class Test extends ArrayObject{

    public function __construct(){
        $this[] = array( 'test' => 'b' );
        $this[] = array( 'test' => 'a' );
        $this[] = array( 'test' => 'd' );
        $this[] = array( 'test' => 'c' );
    }


    public function sort(){
        $this->uasort(function($a, $b) {
            if ($a['test'] == $b['test']) {
                return 0;
            } else {
                return $a['test'] < $b['test'] ? -1 : 1;
            }
        });
    }
}

As anonymous functions only work on PHP 5.3.0 or higher, this would be the more compatible option if you need to target PHP versions below 5.3.0

Below PHP 5.3.0

class Test extends ArrayObject{

    public function __construct(){
        $this[] = array( 'test' => 'b' );
        $this[] = array( 'test' => 'a' );
        $this[] = array( 'test' => 'd' );
        $this[] = array( 'test' => 'c' );
    }


    public function sort(){
        $this->uasort(array($this, 'cmp'));
    }

    public function cmp($a, $b) {
        if ($a['test'] == $b['test']) {
            return 0;
        } else {
            return $a['test'] < $b['test'] ? -1 : 1;
        }
    }

}
Sign up to request clarification or add additional context in comments.

3 Comments

damn, this is interesting, I swore I tried this and it didn't work. Thanks, this is a perfectly workable solution.
what version of php are you using? Anonymous functions didn't become available until PHP 5.3.0
Good point for those that far back. I'm on 5.3.2 (fortunately for this, unfortunately in general).
3

Turns out this was right in the PHP docs (user comments section) -> http://php.net/manual/en/function.uasort.php

magikMaker 4 years ago a quick reminder on the syntax if you want to use uasort in a Class or Object:

<?php 

// procedural: 
uasort($collection, 'my_sort_function'); 

// Object Oriented 
uasort($collection, array($this, 'mySortMethod')); 

// Objet Oriented with static method 
uasort($collection, array('self', 'myStaticSortMethod')); 

?>

2 Comments

I was in the process of typing this out. +1 for actually reading the manual (and comments). Plus, the manual says see usort for details of the compare function and on that page there is an example accessing a static class.
I guess the real deep answer is here in learning about the "callable" type here: php.net/manual/en/language.types.callable.php

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.