# 函数处理

* [call_user_func_array - 调用回调函数，并把一个数组参数作为回调函数的参数](#calluserfuncarray)
* [call_user_func - 调用回调函数，并把一个参数作为回调函数的参数](#calluserfunc)
* [forward_static_call_array - 转发调用静态方法，并把一个数组参数作为静态方法的参数](#forwardstaticcallarray)
* [forward_static_call - 转发调用静态方法，并把一个参数作为静态方法的参数](#forwardstaticcall)
* [func_get_arg - 返回参数列表的某一项](#funcgetarg)
* [func_get_args - 返回一个包含函数参数列表的数组](#funcgetargs)
* [func_num_args - 返回传递给函数的参数个数](#funcnumargs)
* [function_exists - 如果给定的函数已经被定义就返回 true](#functionexists)
* [get_defined_functions - 返回所有已定义函数的数组](#getdefinedfunctions)
* [register_shutdown_function - 注册一个会在 PHP 中止时执行的函数](#registershutdownfunction)
* [register_tick_function - 在每个 Tick 上注册一个执行函数](#registertickfunction)
* [unregister_tick_function - 取消注册每个 Tick 上执行的函数](#unregistertickfunction)

## call_user_func_array

```php
<?php

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return int
 */
function foo(int $a, int $b): int
{
    return $a + $b;
}

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return int
 */
$foo = function (int $a, int $b): int {
    return $a + $b;
};

class Foo
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function method(int $a, int $b): int
    {
        return $a + $b;
    }
}

class Bar
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public static function method(int $a, int $b): int
    {
        return $a + $b;
    }
}

class Baz extends Foo
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function method(int $a, int $b): int
    {
        return $a * $b;
    }
}

class Qux extends Bar
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public static function method(int $a, int $b): int
    {
        return $a * $b;
    }
}

class Quux
{
    /**
     * This method is called when tries to call an object as a function.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function __invoke(int $a, int $b): int
    {
        return $a + $b;
    }
}

var_dump(call_user_func_array('foo', [1, 2]));                         // int(3)
var_dump(call_user_func_array($foo, [1, 2]));                          // int(3)
var_dump(call_user_func_array([new Foo(), 'method'], [1, 2]));         // int(3)
var_dump(call_user_func_array(['Bar', 'method'], [1, 2]));             // int(3)
var_dump(call_user_func_array('Bar::method', [1, 2]));                 // int(3)
var_dump(call_user_func_array([new Baz(), 'parent::method'], [1, 2])); // int(3)
var_dump(call_user_func_array(['Qux', 'parent::method'], [1, 2]));     // int(3)
var_dump(call_user_func_array(new Quux(), [1, 2]));                    // int(3)

```

## call_user_func

```php
<?php

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return int
 */
function foo(int $a, int $b): int
{
    return $a + $b;
}

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return int
 */
$foo = function (int $a, int $b): int {
    return $a + $b;
};

class Foo
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function method(int $a, int $b): int
    {
        return $a + $b;
    }
}

class Bar
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public static function method(int $a, int $b): int
    {
        return $a + $b;
    }
}

class Baz extends Foo
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function method(int $a, int $b): int
    {
        return $a * $b;
    }
}

class Qux extends Bar
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public static function method(int $a, int $b): int
    {
        return $a * $b;
    }
}

class Quux
{
    /**
     * This method is called when tries to call an object as a function.
     *
     * @param  int    $a
     * @param  int    $b
     * @return int
     */
    public function __invoke(int $a, int $b): int
    {
        return $a + $b;
    }
}

var_dump(call_user_func('foo', 1, 2));                         // int(3)
var_dump(call_user_func($foo, 1, 2));                          // int(3)
var_dump(call_user_func([new Foo(), 'method'], 1, 2));         // int(3)
var_dump(call_user_func(['Bar', 'method'], 1, 2));             // int(3)
var_dump(call_user_func('Bar::method', 1, 2));                 // int(3)
var_dump(call_user_func([new Baz(), 'parent::method'], 1, 2)); // int(3)
var_dump(call_user_func(['Qux', 'parent::method'], 1, 2));     // int(3)
var_dump(call_user_func(new Quux(), 1, 2));                    // int(3)

```

## forward_static_call_array

```php
<?php

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return void
 */
function foo(int $a, int $b)
{
    var_dump($a + $b);
}

class Foo
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function method(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Bar
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public static function method(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Baz extends Foo
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function method(int $a, int $b)
    {
        var_dump($a * $b);
    }
}

class Qux extends Bar
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public static function method(int $a, int $b)
    {
        var_dump($a * $b);
    }
}

class Quux
{
    /**
     * This method is called when tries to call an object as a function.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function __invoke(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Quuz
{
    /**
     * Call different methods.
     *
     * @param  void
     * @return void
     */
    public static function method()
    {
        forward_static_call_array('foo', [1, 2]);
        forward_static_call_array([new Foo(), 'method'], [1, 2]);
        forward_static_call_array(['Bar', 'method'], [1, 2]);
        forward_static_call_array('Bar::method', [1, 2]);
        forward_static_call_array([new Baz(), 'parent::method'], [1, 2]);
        forward_static_call_array(['Qux', 'parent::method'], [1, 2]);
        forward_static_call_array(new Quux(), [1, 2]);
    }
}

Quuz::method();
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)

```

## forward_static_call

```php
<?php

/**
 * Calculate the sum of two integers.
 *
 * @param  int    $a
 * @param  int    $b
 * @return void
 */
function foo(int $a, int $b)
{
    var_dump($a + $b);
}

class Foo
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function method(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Bar
{
    /**
     * Calculate the sum of two integers.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public static function method(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Baz extends Foo
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function method(int $a, int $b)
    {
        var_dump($a * $b);
    }
}

class Qux extends Bar
{
    /**
     * Override the parent method.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public static function method(int $a, int $b)
    {
        var_dump($a * $b);
    }
}

class Quux
{
    /**
     * This method is called when tries to call an object as a function.
     *
     * @param  int    $a
     * @param  int    $b
     * @return void
     */
    public function __invoke(int $a, int $b)
    {
        var_dump($a + $b);
    }
}

class Quuz
{
    /**
     * Call different methods.
     *
     * @param  void
     * @return void
     */
    public static function method()
    {
        forward_static_call('foo', 1, 2);
        forward_static_call([new Foo(), 'method'], 1, 2);
        forward_static_call(['Bar', 'method'], 1, 2);
        forward_static_call('Bar::method', 1, 2);
        forward_static_call([new Baz(), 'parent::method'], 1, 2);
        forward_static_call(['Qux', 'parent::method'], 1, 2);
        forward_static_call(new Quux(), 1, 2);
    }
}

Quuz::method();
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)
// int(3)

```

## func_get_arg

```php
<?php

/**
 * Return all item from the argument list.
 *
 * @param  void
 * @return array
 */
function foo(): array
{
    return [func_get_arg(0), func_get_arg(1), func_get_arg(2)];
}

var_dump(foo(1, 2, 3)); // array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

```

## func_get_args

```php
<?php

/**
 * Return all item from the argument list.
 *
 * @param  void
 * @return array
 */
function foo(): array
{
    return func_get_args();
}

var_dump(foo(1, 2, 3)); // array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

```

## func_num_args

```php
<?php

/**
 * Return the number of arguments passed to the function.
 *
 * @param  void
 * @return int
 */
function foo(): int
{
    return func_num_args();
}

var_dump(foo(1, 2, 3)); // int(3)

```

## function_exists

```php
<?php

/**
 * Just a test function.
 *
 * @param  void
 * @return void
 */
function foo()
{
    //
}

var_dump(function_exists('echo'));  // bool(false)
var_dump(function_exists('print')); // bool(false)
var_dump(function_exists('foo'));   // bool(true)

```

## get_defined_functions

```php
<?php

var_dump(get_defined_functions());

```

## register_shutdown_function

```php
<?php

/**
 * Print a string.
 *
 * @param  void
 * @return void
 */
function foo()
{
    var_dump('foo');
}

register_shutdown_function('foo');
exit();
// string(3) "foo"

```

## register_tick_function

```php
<?php

declare(ticks=1);

/**
 * Just a test function.
 *
 * @param  void
 * @return void
 */
function foo()
{
    var_dump('foo');
}

register_tick_function('foo');
$foo = 1;
if ($foo > 0) {
    $foo += 2;
}
// string(3) "foo"
// string(3) "foo"
// string(3) "foo"

```

## unregister_tick_function

```php
<?php

declare(ticks=1);

/**
 * Just a test function.
 *
 * @param  void
 * @return void
 */
function foo()
{
    var_dump('foo');
}

register_tick_function('foo');
unregister_tick_function('foo');
$foo = 1;
if ($foo > 0) {
    $foo += 2;
}
// string(3) "foo"

```

