Урок 16. Использование пользовательских функций в PHP
Теория
Решать задачу кучей кода неудобно. Удобнее всего выносить кусочки кода в отдельные функции. В этом случае получается набор простых функций, каждая из которых выполняет 1 простое действие. Такие функции легко делать, тестировать, использовать для других задач и переносить между проектами.
Задача
Дан массив с числами, записать в новый массив только те элементы, сумма цифр в которых от 1 до 8.
Разрабатывается вспомогательная функция getDigits (параметром принимается число, а возвращается массив цифр). Строку на цифры разбить с помощью str_split:
<?function getDigits($n){return str_split($n,1);}?>
Тестируем функцию на некоем числе:
<?var_dump(getDigits(123))//Выведет [1,2,3]?>
array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" }
Следующая функция - это функция arraySum, параметром принимающая массив и возвращающая сумму элементов этого массива. Пусть эта функция работает и с массивом ['1','2','3'], и с массивом [1,2,3]. Это достигается с помощью функции Number, в которую оборачиваются элементы массива:
<?function arraySum($a){$s=0;foreach($a as$e){$s+=$e;}return$s;}?>
Следующая функция - это функция inRange, которая параметром принимает число и возвращает true, если сумма цифр этого числа от 1 до 8, и false, если иначе.
Вот эта функция:
<?function inRange($n){$s=array_sum(getDigits($n));if($s>=1 and$s<=8){return true;}else{return false;}}?>
Сокращаем код (не работает):
<?function array_sum($n){$s=arraySum(getDigits($n));return$s>=1 and$s<=8;}?>
Решение
Берется массив с числами, переберается циклом и в цикле с помощью функции inRange проверяется, подходит ли этот элемент массива. Если подходит, массив забирается:
<?$a=[8,18,28,13,14,388];$r=[];foreach($a as$e){if(inRange($e)){/*Если подходит, берем*/$r[]=$e;}}var_dump($r)?>
array(3) { [0]=> int(8) [1]=> int(13) [2]=> int(14) }
Задача
Дан массив с числами, найдем сумму всех цифр из этих чисел.
Для решения этой задачей удобно воспользоваться функциями arraySum и getDigits, которые мы разработали при решении предыдущей задачи:
$arr=[12,19, 28,13,14,345];
$sum=0;
foreach($arr as $elem) {
$sum+=array_sum(getDigits($elem));}
echo$sum;
Советы по работе с функциями
Давайте функциям осмысленные имена
Старайтесь давать функциям осмысленные имена. Имя должно отражать то, что делает функция. Предположим, у нас есть функция, которая осуществляет валидацию (проверку правильности заполнения) формы.
Как лучше всего ее назвать? Как-нибудь так: validateForm. И напротив, имя validate или form не будет полностью отражать то, что делает эта функция.
В идеале вы должны посмотреть на имя функции и сразу определить то, что она делает, не заглядывая в ее код.
Не делайте функции очень большими
Функции не должны быть очень большими. Нормальный размер - строк 10. Максимальный - 30 строк.
Если в вашей функции получается больше 30 - задумайтесь о том, чтобы разбить ее на несколько функций.
1 функция - 1 задача
Функции не должны быть многозадачными. Правило такое: 1 функция должна выполнять только 1 задачу.
Предположим, перед вами стоит задача: при регистрации пользователя проверить, не занято ли такое имя, и если не занято - сохранить его в базу данных. Велик соблазн сделать все одной функцией, которая будет проверять, а потом сохранять.
Однако это неправильно. Лучше будет сделать 2 функции: 1 проверяет, а 2-я сохраняет.
Используйте функции внутри функций
Это правило вытекает из предыдущего - внутри функций можно и нужно использовать другие функции, вспомогательные.
Делайте ваши функции универсальными
Старайтесь делать ваши функции как можно более универсальными. Тот проект, который вы делаете сейчас - не последний в вашей жизни и написанные функции вы наверняка будете использовать в будущем. Поэтому при создании новой функции выделите пару минут и хорошо подумайте над ее именем, параметрами и их порядком (с точки зрения удобства).
Практика
Примеры решения задач
Задача. Дан массив с числами. Создайте из него новый массив, где останутся лежать только положительные числа. Создайте для этого вспомогательную функцию isPositive, которая параметром будет принимать число и возвращать true, если число положительное, и false - если отрицательное.
Решение:
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Задачи для решения
Сделайте функцию isNumberInRange, которая параметром принимает число и проверяет, что оно больше 0 и меньше 10. Если это так - пусть функция возвращает true, если не так - false.
Дан массив с числами. Запишите в новый массив только те числа, которые больше 0 и меньше 10. Для этого используйте вспомогательную функцию isNumberInRange из предыдущей задачи.
Сделайте функцию getDigitsSum (digit - это цифра), которая параметром принимает целое число и возвращает сумму его цифр.
Найдите все года от 1 до 2020, сумма цифр которых равна 13. Для этого используйте вспомогательную функцию getDigitsSum из предыдущей задачи.
Сделайте функцию isEven() (even - это четный), которая параметром принимает целое число и проверяет: четное оно или нет. Если четное - пусть функция возвращает true, если нечетное - false.
Дан массив с целыми числами. Создайте из него новый массив, где останутся лежать только четные из этих чисел. Для этого используйте вспомогательную функцию isEven из предыдущей задачи.
Сделайте функцию getDivisors, которая параметром принимает число и возвращает массив его делителей (чисел, на которое делится данное число).
Сделайте функцию getCommonDivisors, которая параметром принимает 2 числа, а возвращает массив их общих делителей. Для этого используйте вспомогательную функцию getDivisors из предыдущей задачи.