Функции обратного вызова в PHP

Функции обратного вызова в PHP

От автора: в данном уроке я хотел бы поговорить о приеме, который достаточно редко используется в создании скриптов на языке PHP, особенно на ранних этапах изучения языка. Речь идет о функциях быстрого вызова. Поэтому в данном уроке мы разберем, что это такое и каких видов они бывают.

скачать исходникискачать урок

1. Постановка задачи

Итак, давайте рассмотрим следующий пример. Есть три текстовых файла, каждый из которых содержит определенный набор чисел. Вот содержимое одного из файлов:

11
2
10
5
11
1
10
5
10
20

Для чтения этих файлов предусмотрен специальный класс, следующего содержания:

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 "</pre>";

Данный класс довольно простой и содержит всего один метод get_numbers(). Этот метод принимает в качестве аргумента массив $files, в котором содержатся имена фалов для чтения. После проверки наличия данных файлов, мы выполняем их чтение, и содержимое, записываем в предварительно в переменную $data, а затем в свойство $numbers. Давайте посмотрим в браузере, выведет данный код:

Класс свою задачу выполняет, но что делать, если скажем, через некоторое время необходимо будет, определенным образом обрабатывать данные полученные из файлов. К примеру, умножить на число, либо добавить строку и т.д. При этом придется переписывать код данного метода, так как он не универсален и выполняет только одну поставленную задачу. Поэтому в данном уроке мы добавим универсальности данному классу, используя функции обратного вызова.

2. Модернизация класса

Первым делом определимся, что такое функции обратного вызова. Функции обратного вызова (callback) – предусматривает передачу определенного исполняемого кода в качестве одного из параметров для другого кода. То есть обратный вызов функций позволяет в определенном методе исполнять код, который задается в ее аргументах. Функции обратного вызова, это — как правило обычные функции, которые напрямую ни когда не вызываются.

Прямой вызов функции: function(). Функции обратного вызова обычно передаются как параметр для другой функции. И при этом мы передаем указатель (ссылку) на функцию. Сейчас давайте изменим код метода get_numbers(), следующим образом:

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. Классическая функция — как функция обратного вызова. Давайте создадим такую функцию. Не забывая о параметрах, какие она должна принимать:

function my_callback3($file, $data) {
	foreach($data as $item) {
			$res = $item * 100;
			$arr[] = $res." *100";
		}
		return $arr;
}

2. Статический метод класса – как функция обратного вызова. Давайте создадим класс и добавим в него такой метод:

class MyClass {
	public static function my_callback($file, $data) {
		foreach($data as $item) {
			$arr[] = $item." from file - ".$file;
		}
		return $arr;
	}
}

3. Обычный метод класса – как функция обратного вызова. Давайте добавим данный метод к ранее созданному классу MyClass:

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() и посмотрим, как передать параметром функцию обратного вызова, каждого из типов. Итак, как обычно вызывать метод мы будем следующим образом:

$result = $obj->get_numbers($files,$callback);
echo "<pre>";
print_r($result);
echo "</pre>";

В переменной $callback будем хранить указатель на функцию обратного вызова. Значит, для вызова каждого из типов, достаточно определить данную переменную перед кодом вызова. Теперь для функции обратного вызова первого типа:

$callback = "my_callback3";

И соответственно на экране мы увидим следующее:

Для второго типа:

$callback = array("MyClass","my_callback");

Так как второй тип – это статический класс, значит в переменной $callback, необходимо сохранить массив. В первой ячейке которого, указываем класс, в котором описан данный статический метод. Во второй ячейке указываем имя статического метода. На экране мы увидим следующее:

Для третьего типа:

$callback = array(new MyClass(),"my_callback2");

Так как второй тип – это обычный метод, значит необходимо все также определить в переменной $callback массив, в первой ячейке которого сохранить объект класса, в котором описан нужный метод. А во второй ячейке указать имя метода. На экране мы увидим следующее:

Как Вы видите, при вызове функций обратного вызова мы изменяем действие метода get_numbers(). И в завершении данного урока, хотел бы показать еще два способа, создания функций обратного вызова:

1. Создание анонимной функции и сохранение указателя на нее, в переменной:

$callback = function($file,$data) {
	foreach($data as $item) {
			$res = $item * 1000;
			$arr[] = $res." *1000";
		}
		return $arr;
};

При этом на экране мы увидим следующее:

2. Создание функции при помощи функции create_function() (первый параметр это строка передаваемых аргументов, второй – строка кода функции):

$callback = create_function('$file,$data','foreach($data as $item) {$res = $item / 1000;$arr[] = $res."/1000";}return $arr;');

На экране мы увидим следующее:

Как Вы видите использование данных функций, добавляет универсальности и гибкости создаваемым скриптам. Поэтому в некоторых случаях их очень полезно и нужно использовать.

На этом данный урок завершен. Всего Вам доброго и удачного кодирования!!!

Фреймворк YII2: теория и первая практика

Овладейте азами фреймворка Yii2 за 5 дней!

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (1)

  1. Tolik

    спасибо за урок!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree