DEV Community

Ngo Dinh Cuong
Ngo Dinh Cuong

Posted on • Updated on

Understand more magic methods: __callStatic()

As you know, magic methods are special methods which override PHP's default's action when certain actions are performed on an object. The following method names are considered magical: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone(), and __debugInfo(). All magic methods, with the exception of __construct(), __destruct(), and __clone(), must be declared as public, otherwise an E_WARNING is emitted.

__callStatic() is method overloading, triggered when invoking inaccessible methods in a static context.

public static __callStatic(string $name, array $arguments): mixed
Enter fullscreen mode Exit fullscreen mode

The $name argument is the name of the method being called. The $arguments argument is an enumerated array containing the parameters passed to the $name'ed method.

With regard to __callStatic(), you can call a method via double colon, and rename functions to short/pretty name

class Str
{
    /**
     * Shortcut methods
     */
    private static $methods = [
        'chunk' => 'chunk_split',
        'split' => 'str_split',
        'length' => 'strlen',
        'reverse' => 'strrev',
        'countWord' => 'str_word_count',
    ];

    /**
     * Trigger when invoking inaccessible methods in a static context
     */
    public static function __callStatic(string $method, array $parameters)
    {
        if (!array_key_exists($method, self::$methods)) {
            throw new Exception('The ' . $method . ' is not supported.');
        }

        return call_user_func_array(self::$methods[$method], $parameters);
    }

    /**
     * Parse query string to varaibles
     */
    public static function parse(string $str)
    {
        parse_str($str, $output);
        return $output;
    }
}

$data = "Happy New Year!";
$countWord = Str::countWord($data, 1);
var_dump($countWord);

$queryStr = "first=value&arr[]=foo+bar&arr[]=baz";
$output = Str::parse($queryStr);
var_dump($output);
Enter fullscreen mode Exit fullscreen mode
class Arr
{
    /**
     * Shortcut methods
     */
    private static $methods = [
        'search' => 'array_search',
        'chunk' => 'array_chunk',
        'combine' => 'array_combine',
        'count' => 'array_count_values'
    ];

    /**
     * Trigger when invoking inaccessible methods in a static context
     */
    public static function __callStatic(string $method, array $parameters)
    {
        if (!array_key_exists($method, self::$methods)) {
            throw new Exception('The ' . $method . ' is not supported.');
        }

        return call_user_func_array(self::$methods[$method], $parameters);
    }

    /**
     * Count all elements in an array
     */
    public static function length(array $arr)
    {
        return count($arr);
    }
}

$arr = [1,2,3,4,5];
$arr2 = [9,8,7,6,5];

$rs = Arr::combine($arr, $arr2);
var_dump($rs);

$length = Arr::length($arr);
var_dump($length);
Enter fullscreen mode Exit fullscreen mode

Another way uses this overloading method that you can define your own function without static keyword, access using double colon. However, this way restricts you must define methods as protected

class Helper
{
    /**
     * __callStatic
     * @param  string $method
     * @param  mixed $args
     * @return void
     */
    public static function __callStatic($method, $args) {
        $called = get_called_class();
        $class = new $called();
        return $class->$method(...$args);
    }

    protected function generateToken($length)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }
}

$result = Helper::generateToken(10);
var_dump($result);
Enter fullscreen mode Exit fullscreen mode

Discussion (0)