Wednesday, 4 August 2021

PHP Magic method __Call() , call_user_func_array, usage() highlights

 __call() is triggered when invoking inaccessible methods in an object context.

https://www.php.net/manual/en/language.oop5.overloading.php#object.call



call_user_func_array — Call a callback with an array of parameters

https://www.php.net/manual/en/function.call-user-func-array.php

https://stackoverflow.com/questions/18526060/why-should-one-prefer-call-user-func-array-over-regular-calling-of-function

<?php
function foobar($arg$arg2) {
    echo 
__FUNCTION__" got $arg and $arg2\n";
}
class 
foo {
    function 
bar($arg$arg2) {
        echo 
__METHOD__" got $arg and $arg2\n";
    }
}


// Call the foobar() function with 2 arguments
call_user_func_array("foobar", array("one""two"));

// Call the $foo->bar() method with 2 arguments
$foo = new foo;
call_user_func_array(array($foo"bar"), array("three""four"
));
?>


You have an array with the arguments for your function which is of indeterminate length.

$args = someFuncWhichReturnsTheArgs();

foobar( /* put these $args here, you do not know how many there are */ );

The alternative would be:

switch (count($args)) {
    case 1:
        foobar($args[0]);
        break;
    case 2:
        foobar($args[0], $args[1]);
        break;
    ...
}
// Real example, call model service which is instance of model class, $name is name of function in model class, and $arugments is function arguments in array
call_user_func_array([$this->modelService, $name], $arguments);
------------------Real use of __Call() and call_user_func_array in a class
---------------------------------------
namespace App\Services\ControllerServices;

abstract class BaseControllerService
{    
	/**
     * @var object
     */
    protected $modelService;

    /**
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array([$this->modelService, $name], $arguments);
    }


}
--------------------------------------
namespace App\Services\ControllerServices;

use App\Services\ModelServices\DummyModelService;

class DummyControllerService extends BaseControllerService
{

    /*
    * Holds product model service
    */
    public $modelService;

    /**
     * Create a new AuthController instance.
     * @return void
     */
    public function __construct()
    {
        $this->modelService = new DummyModelService();
    }


}

-----------------------------------------
namespace App\Services\ModelServices;

class DummyModelService extends BaseModelService
{

	public function saveToDB() {
	}

}

--------------------------------------

namespace App\Services\ControllerServices;

use App\Services\ControllerServices\DummyControllerService;

class testerControllerService {

	public function test() {
		$service = new DummyControllerService();

		$servuce->saveToDB();
	
	}

}
-----------------------------------------------------------------------



No comments:

Post a Comment