От автора: в данном уроке я хотел бы поговорить о приеме, который достаточно редко используется в создании скриптов на языке PHP, особенно на ранних этапах изучения языка. Речь идет о функциях быстрого вызова. Поэтому в данном уроке мы разберем, что это такое и каких видов они бывают.
1. Постановка задачи
Итак, давайте рассмотрим следующий пример. Есть три текстовых файла, каждый из которых содержит определенный набор чисел. Вот содержимое одного из файлов:
1 2 3 4 5 6 7 8 9 10 |
11 2 10 5 11 1 10 5 10 20 |
Для чтения этих файлов предусмотрен специальный класс, следующего содержания:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Math { public $numbers; public function get_numbers($files) { if(is_array($files)) { foreach ($files as $file) { if(file_exists($file.".txt")) { $data = file($file.".txt"); $this->numbers[$file] = $data; } } return $this->numbers; } } } $files = array( 'numbers_1', 'numbers_2', 'numbers_3' ); $obj = new Math(); $result = $obj->get_numbers($files); echo "<pre>"; print_r($result); echo " |
»;
Данный класс довольно простой и содержит всего один метод get_numbers(). Этот метод принимает в качестве аргумента массив $files, в котором содержатся имена фалов для чтения. После проверки наличия данных файлов, мы выполняем их чтение, и содержимое, записываем в предварительно в переменную $data, а затем в свойство $numbers. Давайте посмотрим в браузере, выведет данный код:
Класс свою задачу выполняет, но что делать, если скажем, через некоторое время необходимо будет, определенным образом обрабатывать данные полученные из файлов. К примеру, умножить на число, либо добавить строку и т.д. При этом придется переписывать код данного метода, так как он не универсален и выполняет только одну поставленную задачу. Поэтому в данном уроке мы добавим универсальности данному классу, используя функции обратного вызова.
2. Модернизация класса
Первым делом определимся, что такое функции обратного вызова. Функции обратного вызова (callback) – предусматривает передачу определенного исполняемого кода в качестве одного из параметров для другого кода. То есть обратный вызов функций позволяет в определенном методе исполнять код, который задается в ее аргументах. Функции обратного вызова, это — как правило обычные функции, которые напрямую ни когда не вызываются.
Прямой вызов функции: function(). Функции обратного вызова обычно передаются как параметр для другой функции. И при этом мы передаем указатель (ссылку) на функцию. Сейчас давайте изменим код метода get_numbers(), следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public function get_numbers($files, $callback = FALSE) { if(is_array($files)) { foreach ($files as $file) { if(file_exists($file.".txt")) { $data = file($file.".txt"); if(is_callable($callback)) { $data = call_user_func($callback, $file, $data); } $this->numbers[$file] = $data; } } return $this->numbers; } } |
Первое, что добавлено – это второй необязательный аргумент $callback = FALSE. Это и есть указатель на ссылку обратного вызова. Который, по умолчанию равен FALSE. И второе, добавлена проверка: если в переменной $callback содержится указатель на функцию обратного вызова. Значит необходимо вызвать данную функцию. Для этого нужно, проверить – а можно ли вызвать функцию, указатель на которую сохранен в переменной $callback. Для этого используется функция is_callable($callback), которая в качестве аргумента принимает указатель на функцию. Она вернет TRUE, если функцию действительно можно вызвать на исполнение.
Для вызова функций обратного вызова применяют стандартную функцию: call_user_func($callback, $file, $data), которая первым параметром принимает указатель на функцию, а последующими — аргументы, которые должны быть переданы при вызове функции.
Таким образом, мы закладываем при создании метода – некую универсальность. В нужный момент, если нам необходимо будет каким то образом повлиять на возвращаемые данные. Нам достаточно будет создать функцию обратного вызова и передать ее указатель в качестве параметра для метода get_numbers().
3. Создание функций обратного вызова
Различают три основных вида функций обратного вызова:
1. Классическая функция — как функция обратного вызова. Давайте создадим такую функцию. Не забывая о параметрах, какие она должна принимать:
1 2 3 4 5 6 7 |
function my_callback3($file, $data) { foreach($data as $item) { $res = $item * 100; $arr[] = $res." *100"; } return $arr; } |
2. Статический метод класса – как функция обратного вызова. Давайте создадим класс и добавим в него такой метод:
1 2 3 4 5 6 7 8 |
class MyClass { public static function my_callback($file, $data) { foreach($data as $item) { $arr[] = $item." from file - ".$file; } return $arr; } } |
3. Обычный метод класса – как функция обратного вызова. Давайте добавим данный метод к ранее созданному классу MyClass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class MyClass { public static function my_callback($file, $data) { foreach($data as $item) { $arr[] = $item." from file - ".$file; } return $arr; } public function my_callback2($file, $data) { foreach($data as $item) { $res = $item / 100; $arr[] = $res." /100"; } return $arr; } } |
Теперь давайте, вызовем метод get_numbers() и посмотрим, как передать параметром функцию обратного вызова, каждого из типов. Итак, как обычно вызывать метод мы будем следующим образом:
1 2 3 4 |
$result = $obj->get_numbers($files,$callback); echo "<pre>"; print_r($result); echo " |
»;
В переменной $callback будем хранить указатель на функцию обратного вызова. Значит, для вызова каждого из типов, достаточно определить данную переменную перед кодом вызова. Теперь для функции обратного вызова первого типа:
1 |
$callback = "my_callback3"; |
И соответственно на экране мы увидим следующее:
Для второго типа:
1 |
$callback = array("MyClass","my_callback"); |
Так как второй тип – это статический класс, значит в переменной $callback, необходимо сохранить массив. В первой ячейке которого, указываем класс, в котором описан данный статический метод. Во второй ячейке указываем имя статического метода. На экране мы увидим следующее:
Для третьего типа:
1 |
$callback = array(new MyClass(),"my_callback2"); |
Так как второй тип – это обычный метод, значит необходимо все также определить в переменной $callback массив, в первой ячейке которого сохранить объект класса, в котором описан нужный метод. А во второй ячейке указать имя метода. На экране мы увидим следующее:
Как Вы видите, при вызове функций обратного вызова мы изменяем действие метода get_numbers(). И в завершении данного урока, хотел бы показать еще два способа, создания функций обратного вызова:
1. Создание анонимной функции и сохранение указателя на нее, в переменной:
1 2 3 4 5 6 7 |
$callback = function($file,$data) { foreach($data as $item) { $res = $item * 1000; $arr[] = $res." *1000"; } return $arr; }; |
При этом на экране мы увидим следующее:
2. Создание функции при помощи функции create_function() (первый параметр это строка передаваемых аргументов, второй – строка кода функции):
1 |
$callback = create_function('$file,$data','foreach($data as $item) {$res = $item / 1000;$arr[] = $res."/1000";}return $arr;'); |
На экране мы увидим следующее:
Как Вы видите использование данных функций, добавляет универсальности и гибкости создаваемым скриптам. Поэтому в некоторых случаях их очень полезно и нужно использовать.
На этом данный урок завершен. Всего Вам доброго и удачного кодирования!!!
Комментарии (1)