Заметки WEB-разработчика

Полезные материалы для web-разработки

Callback функции (функции обратного вызова) в php

В этой статье приводятся примеры вызовов callback-функций в php (вызов статического метода класса, вызов метода объекта, вызов внутри класса и т.д.) 

Callback функции (функции обратного вызова) в php

Callback (англ. call — вызов, англ. back — обратный) или фу́нкция обра́тного вы́зова в программировании — передача исполняемого кода в качестве одного из параметров другого кода. Обратный вызов позволяет в функции исполнять код, который задаётся в аргументах при её вызове.

Некоторые функции, такие как call_user_func() или usort() принимают в качестве параметра определенные пользователем callback-функции. Callback-функции могут быть не только простыми функциями, но также и методами объектов, включая статические методы классов.

PHP-функция передается просто как строка ее имени. Можно использовать любую встроенную или пользовательскую функцию, кроме языковых конструкций, таких как: array(), echo(), empty(), eval(), exit(), isset(), list(), print() и unset().

Метод созданного объекта передается как массив, содержащий сам объект в элементе с индексом 0 и имя метода в элементе с индексом 1.

Статические методы классов также могут быть переданы без создания экземпляра объекта данного класса путем передачи имени класса вместо имени объекта в элементе с индексом 0.

Кроме общих пользовательских функций, create_function() также может быть использована для создания анонимной callback-функции. Начиная с версии PHP 5.3.0 стала возможным также передача замыканий в callback-параметр.

Примеры callback-функций

Вариант 1: простой вызов callback

function barber($type) 
{
	echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");

Вариант 2: вызов статического метода класса

class myclass {
  static function say_hello($v) {
  	echo "Hello!\n".$v;
  }
}
call_user_func(array('myclass', 'say_hello'), 'params'); 
// Hello! params

Вариант 3: вызов метода объекта

class myclass {
  function say_hello($v) 
  {
    echo "Hello!\n".$v;
  }
}
$obj = new myclass();
call_user_func(array($obj, 'say_hello'), 'params');

Вариант 4: вызов относительного статического метода класса (с версии PHP 5.3.0)

class A {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}
call_user_func(array('B', 'parent::who')); // A

Вариант 5: вызов внутри класса

class my_array {  
    function __construct($arr) {
        $this->arr = $arr; 
    }
    private function cmp($a, $b) {
        if ($a == $b) {
            return 0;
        }
        return ($a['tel'] < $b['tel']) ? -1 : 1;
        // сортируем по ключу tel
    }
    public function my_sort() { 
        usort($this->arr, array($this, 'cmp'));
        return $this->arr;
    }
}

Достоинства и недостатки

Достоинства:

  • Возможность динамического изменения функциональности (подключения и отключения плагинов/модулей при работе программы).
  • Возможность неограниченного количества вариантов вызываемой функции без изменения базового (в данном контексте) кода.
  • Возможность вставки вызываемой функции не только для альтернативного поведения, но и в качестве ещё одной (промежуточной) подпрограммы — обычно для отслеживания операций или изменения параметров для следующей (вызываемой) функции. Таких независимых «дополнительных звеньев» в цепочке вызовов может быть сколько угодно.
  • Поддержка функций обратного вызова в большинстве современных языков программирования общего назначения.

Недостатки:

  • Уменьшение производительности, связанной с дополнительными вызовами «обратной функции» — прямо пропорционально «стоимости вызова функции» в среде выполнения и количеству дополнительных вызовов при работе программы.
  • Ухудшение читаемости исходного кода — для понимания алгоритма программы необходимо отслеживать всю цепочку вызовов.

Комментарии

Комментарии через Вконтакте