30

I want to use array_map with a static method but I fail. Here is my code :

Class Buy {

    public function payAllBills() {
        $bill_list = OtherClass::getBillList();
        return array_map(array(self, 'pay'), $bill_list); // Issue line
    }

    private static function pay($bill) {
        // Some stuff
        return true;
    }

}

PHP gives me the error :

Use of undefined constant self - assumed 'self'

I have also tried :

return array_map('self::makeBean()', $model_list);

But it doesn't work.

Do you have any idea how to use array_map with static method ?

I have already read : Can a method be used as a array_map function in PHP 5.2? but this question is about standard methods, not statics.

Community
  • 1
  • 1
Samuel Dauzon
  • 10,744
  • 13
  • 61
  • 94

4 Answers4

51

As per the documentation,

return array_map('self::pay', $model_list);

Note that your attempt included () in the method name string, which would be wrong

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
12

Let me extend @mark-baker's answer:

if you want to call a static method of another class, you have to put the full namespace into the quotes:

return array_map('Other\namespace\CustomClass::pay', $model_list);

Using the class per use is not enough:

// this is not enough:
// use Other\namespace\CustomClass;
return array_map('CustomClass::pay', $model_list); //does not work
olidem
  • 1,961
  • 2
  • 20
  • 45
  • If you were to use this a class, this will clutter the code (multiple references on the same code). A solution to this is to make a private function and array_map over that. `use Other\namespace\CustomClass; class myClass { private function pay($var) { return CostomClass::pay($var); } public function payMe($model_list) { return array_map([$this, 'pay'], $model_list);} } ` – DJQ Oct 28 '21 at 14:46
9

According to the docs:

Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0.

There are several ways for a class to reference it's own name, depending on the situation. One clean, efficient way in PHP 5.5+ is self::class (class keyword). (Note: It's also a particularly good method to use if you're using a code editor with intellisense, because the editor can then properly identify the class reference for doing things like renaming and go-to-references.)

So, you can do the following:

array_map([self::class, 'pay'], $bill_list);

This also works when you're referring to a static method on some other namespaced class, like so:

use Some\Cool\OtherClass;

array_map([OtherClass::class, 'pay'], $bill_list);
wunch
  • 1,092
  • 9
  • 12
  • Just a heads up, this works but for those like me (without enough coffe) do note that `OtherClass::class` is **not a string**, it's called directly. So pay attention to call it *without* quotes. – Gruber Aug 24 '23 at 05:58
1

PHP 5.6 - 7.3:

array_map('self::pay'], $bill_list); # works
array_map(['self', 'pay'], $bill_list); # works

array_map('\\Some\\Name\\Space\\SomeClass::method',$array); # works
array_map(['\\Some\\Name\\Space\\SomeClass','method'],$array); # works

use \Some\Name\Space\SomeClass;  # alias to local namespace fails:
array_map('SomeClass::method',$array); # fails
array_map(['SomeClass','method'],$array); # fails

The error given is:

PHP Warning: array_map() expects parameter 1 to be a valid callback, class 'SomeClass' not found

use SomeLongClassName as Foo; # alias within namespace fails:
array_map("Foo::method",$array); # fails
array_map(['Foo','method'],$array); # fails

The error given is:

PHP Warning: array_map() expects parameter 1 to be a valid callback, class 'Foo' not found

One workaround to shorten the line length and/or re-use it:

const SomeClass = '\\Some\\Name\\Space\\SomeClass';
array_map([SomeClass,'method'],$array); # works

or if you use the foreign static method many times over in a class:

class MyClass{
    # in PHP 7.1+ you can make this private:
    const SCMethod = '\\Some\\Name\\Space\\SomeClass::method';

    public function myMethod($array){
        return array_map(self::SCMethod, $array); # works
    }
}
Wil
  • 757
  • 9
  • 12