php array_map with static method of object
Asked Answered
R

4

32

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.

Recidivate answered 26/1, 2016 at 9:19 Comment(4)
Try this:- array_map(array(new Buy, 'pay'), $bill_list);Counterrevolution
Thanks Ravi Hirani because your solution works too.Recidivate
PHP5.2 Wow, worried that all these newer version (5.3, 5.4, 5.5, 5.6) may have bugs iI supposeIntercross
Don't worry, I use 5.6, but I had found only this question about array_map and method :)Recidivate
S
55

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

Sibylsibylla answered 26/1, 2016 at 9:26 Comment(1)
this syntax is deprecated, use array_map(self::pay(...), $someList) or array_map(self::class . '::pay', $someList) instead.Motorway
V
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
Vendor answered 31/12, 2018 at 12:9 Comment(1)
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);} } Bounds
L
10

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);
Lenhard answered 23/10, 2020 at 1:4 Comment(2)
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.Arieariel
I was gonna comment that calling a method by name in a string could confuse the IDE code completion but to my surprise this is recognized! At least PhpStorm (2023.2) recognizes the references both ways. Great answer!Ezzell
L
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
    }
}
Ludivinaludlew answered 13/4, 2020 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.