Salar
Salar

Reputation: 5509

php call static function of class dynamically(function name is unknown)

Here is my Class:

class ProcessUploadedExcel {
 public static function test1($a,$b)
    {
        dd('hi');
    }
 public static function test2($a,$b)
    {
        dd('hi');
    }

}

in another file I want to call one of the functions. So I included the file:

use App\Library\ProcessUploadedExcel;

the function is stored in a variable and when I use call_user_func_array I get an error:

ProcessUploadedExcel::test1(1,2);//works fine.

$func_name = 'test1';
call_user_func_array("ProcessUploadedExcel::" . $func_name, [1,2]);//gets error

error:

call_user_func_array() expects parameter 1 to be a valid callback, class 'ProcessUploadedExcel' not found

Upvotes: 1

Views: 120

Answers (4)

jspit
jspit

Reputation: 7703

You can do this:

class ProcessUploadedExcel {
 public static function test1($a,$b)
    {
        //dd('hi');
        var_dump($a,$b);
    }
 public static function test2($a,$b)
    {
        dd('hi');
    }
}

$func_name = 'test1';
ProcessUploadedExcel::$func_name(1,2);

Output:

int(1) int(2)

or if you want to use call_user_func_array()

call_user_func_array([ProcessUploadedExcel::class,$func_name],[1,2]);

Both solutions work properly with use and namespaces.

Upvotes: 3

Dmitry Leiko
Dmitry Leiko

Reputation: 4382

You can try this way:

class ProcessUploadedExcel {
    public static function test1($a,$b)
    {
        echo ('hi');
    }
    public static function test2($a,$b)
    {
        echo ('hi');
    }

}

$func_name = 'test1';
call_user_func_array([ ProcessUploadedExcel::class, $func_name ] , [1,2]);

Upvotes: 2

Amin Fazlali
Amin Fazlali

Reputation: 1237

call_user_func_array ignores the use and you have to provide the full path:

$func_name = 'test1';
call_user_func_array("App\Library\ProcessUploadedExcel::" . $func_name, [1,2]);

Upvotes: 2

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17415

First misconception is that you "included the file: use App\Library\ProcessUploadedExcel;". No, you just told PHP that whenever it encounters ProcessUploadedExcel, you actually mean App\Library\ProcessUploadedExcel. This doesn't include anything. Including something is a different mechanism using require or require_once. Actually including the file is done by the autoloader in most projects.

Now, you pass a string to call_user_func_array(). PHP doesn't look inside that string, so it can't tell that you mean something different than what you write there. Inside the called function, where the string is used, the above use ... is not effective, so the function fails since it can't find the according callback.

Remedies:

  • You could provide the fully qualified name "App\\Library\\ProcessUploadedExcel::test1" as parameter.
  • You could make PHP look up the fully qualified name for you using ProcessUploadedExcel::class . "::test1".

I'm not sure that either of these works though, but check the documentation which way to specify a callback exist. Maybe you need to specify class and function separately like [ProcessUploadedExcel::class, "test1"].

Upvotes: 0

Related Questions