8. Функции

Введение
Заголовок раздела «Введение»Функции — это переиспользуемые блоки кода. Они помогают организовать программу, избежать дублирования и упростить тестирование.
Зачем нужны функции?
Заголовок раздела «Зачем нужны функции?»- DRY принцип (Don’t Repeat Yourself) — не повторяйся
- Модульность — код разбит на логические части
- Тестируемость — каждую функцию можно протестировать отдельно
- Читаемость — функции с хорошими именами документируют код
Объявление функций
Заголовок раздела «Объявление функций»Базовый синтаксис
Заголовок раздела «Базовый синтаксис»<?php// Простейшая функцияfunction sayHello() { echo "Привет!";}
sayHello(); // Привет!
// Функция с параметрамиfunction greet($name) { echo "Привет, $name!";}
greet("Иван"); // Привет, Иван!
// Функция с возвратом значенияfunction add($a, $b) { return $a + $b;}
$result = add(5, 3);echo $result; // 8?>```text
### Параметры по умолчанию
```php<?phpfunction greet($name = "Гость", $greeting = "Привет") { return "$greeting, $name!";}
echo greet(); // Привет, Гость!echo greet("Иван"); // Привет, Иван!echo greet("Мария", "Доброе утро"); // Доброе утро, Мария!?>```text
### Именованные аргументы (PHP 8+)
```php<?phpfunction createUser($name, $email, $age, $role = 'user') { return [ 'name' => $name, 'email' => $email, 'age' => $age, 'role' => $role ];}
// Обычный вызов
// Именованные аргументы (PHP 8+)$user2 = createUser( name: "Мария", age: 30, role: "admin");
// Можно менять порядок$user3 = createUser( age: 28, name: "Петр",);?>```text
## Type Hints и Return Types
### Скалярные типы (PHP 7+)
```php<?phpdeclare(strict_types=1);
function calculateTax(float $amount, float $rate): float { return $amount * $rate;}
$tax = calculateTax(1000.00, 0.20);echo $tax; // 200.0
// Строгая типизация// calculateTax("1000", 0.20); // TypeError!?>```text
### Составные типы
```php<?phpdeclare(strict_types=1);
function getUserData(int $id): array { return [ 'id' => $id, 'name' => 'User_' . $id, 'email' => "user{$id}@example.com" ];}
function formatUser(array $user): string { return "{$user['name']} ({$user['email']})";}
$user = getUserData(42);echo formatUser($user);?>```text
### Nullable types (PHP 7.1+)
```php<?phpdeclare(strict_types=1);
function findUserByEmail(?string $email): ?array { if ($email === null) { return null; }
// Поиск пользователя... return ['name' => 'Admin', 'email' => $email]; }
return null; // Не найден}
$user = findUserByEmail(null); // null?>```text
### Union types (PHP 8+)
```php<?phpfunction processId(int|string $id): string { if (is_int($id)) { return "ID: " . $id; } return "Slug: " . $id;}
echo processId(42); // ID: 42echo processId("home"); // Slug: home
// Несколько типов возвратаfunction getData(string $key): array|string|null { $data = [ 'config' => ['theme' => 'dark'], 'title' => 'My Site' ];
return $data[$key] ?? null;}?>```text
## Область видимости переменных
### Глобальные переменные
```php<?php$globalVar = "Я глобальная";
function test() { // ❌ Не работает // echo $globalVar; // Undefined variable
// ✅ Используем global global $globalVar; echo $globalVar;}
test(); // Я глобальная
// Альтернатива: $GLOBALSfunction test2() { echo $GLOBALS['globalVar'];}?>```text
### Статические переменные
```php<?phpfunction counter() { static $count = 0; // Сохраняется между вызовами $count++; return $count;}
echo counter(); // 1echo counter(); // 2echo counter(); // 3
// Практический пример: генерация уникальных IDfunction generateId() { static $id = 0; return ++$id;}
echo generateId(); // 1echo generateId(); // 2?>```text
## Передача параметров
### По значению (по умолчанию)
```php<?phpfunction increment($num) { $num++; echo "Внутри функции: $num";}
$value = 5;increment($value); // Внутри функции: 6echo $value; // 5 (не изменилось!)?>```text
### По ссылке
```php<?phpfunction increment(&$num) { $num++; echo "Внутри функции: $num";}
$value = 5;increment($value); // Внутри функции: 6echo $value; // 6 (изменилось!)
// Практический примерfunction addTax(&$price, $taxRate) { $price = $price * (1 + $taxRate);}
$productPrice = 1000;addTax($productPrice, 0.20);echo $productPrice; // 1200?>```text
## Вариативные функции
### Переменное количество аргументов
```php<?php// Старый способ: func_get_args()function sum_old() { $args = func_get_args(); return array_sum($args);}
echo sum_old(1, 2, 3, 4, 5); // 15
// Новый способ: ... оператор (PHP 5.6+)function sum(...$numbers) { return array_sum($numbers);}
echo sum(1, 2, 3, 4, 5); // 15echo sum(10, 20); // 30
// Смешивание с обычными параметрамиfunction formatList(string $separator, ...$items) { return implode($separator, $items);}
echo formatList(", ", "яблоко", "банан", "апельсин");// яблоко, банан, апельсин?>```text
### Распаковка массивов
```php<?phpfunction add($a, $b, $c) { return $a + $b + $c;}
$numbers = [1, 2, 3];echo add(...$numbers); // 6 (распаковка)
// То же чтоecho add($numbers[0], $numbers[1], $numbers[2]);?>```text
## Анонимные функции (Closures)
### Базовое использование
```php<?php// Анонимная функция$greet = function($name) { return "Привет, $name!";};
echo $greet("Иван"); // Привет, Иван!
// Передача как callback$numbers = [1, 2, 3, 4, 5];
$squared = array_map(function($n) { return $n * $n;}, $numbers);
print_r($squared); // [1, 4, 9, 16, 25]?>```text
### Замыкания и use
```php<?php$message = "Привет";
$greet = function($name) use ($message) { return "$message, $name!";};
echo $greet("Иван"); // Привет, Иван!
// Изменение внешней переменной$counter = 0;
$increment = function() use (&$counter) { $counter++;};
$increment();$increment();echo $counter; // 2?>```text
## Стрелочные функции (PHP 7.4+)
```php<?php// Обычная анонимная функция$multiply = function($x, $y) { return $x * $y;};
// Стрелочная функция (короче!)$multiply = fn($x, $y) => $x * $y;
echo $multiply(5, 3); // 15
// Автоматический use (не нужен!)$factor = 10;
// Старый способ$scale_old = function($n) use ($factor) { return $n * $factor;};
// Новый способ$scale = fn($n) => $n * $factor;
echo $scale(5); // 50
// С array_map$numbers = [1, 2, 3, 4, 5];$doubled = array_map(fn($n) => $n * 2, $numbers);print_r($doubled); // [2, 4, 6, 8, 10]?>```text
## Рекурсия
### Факториал
```php<?phpfunction factorial($n) { if ($n <= 1) { return 1; } return $n * factorial($n - 1);}
echo factorial(5); // 120 (5! = 5*4*3*2*1)?>```text
### Числа Фибоначчи
```php<?phpfunction fibonacci($n) { if ($n <= 1) { return $n; } return fibonacci($n - 1) + fibonacci($n - 2);}
for ($i = 0; $i < 10; $i++) { echo fibonacci($i) . " ";}// 0 1 1 2 3 5 8 13 21 34?>```text
### Обход дерева директорий
```php<?phpfunction scanDirectory($dir, $prefix = "") { $files = scandir($dir);
foreach ($files as $file) { if ($file === '.' || $file === '..') continue;
$path = $dir . '/' . $file; echo $prefix . $file . "";
if (is_dir($path)) { scanDirectory($path, $prefix . " "); // Рекурсия } }}
scanDirectory("./my_folder");?>```text
## Встроенные функции PHP
### Работа со строками
```php<?php$str = "Hello, World!";
strlen($str); // 13 (длина)strtoupper($str); // "HELLO, WORLD!"strtolower($str); // "hello, world!"str_replace("World", "PHP", $str); // "Hello, PHP!"substr($str, 0, 5); // "Hello"strpos($str, "World"); // 7 (позиция)?>```text
### Работа с массивами
```php<?php$arr = [1, 2, 3, 4, 5];
count($arr); // 5array_sum($arr); // 15array_product($arr); // 120max($arr); // 5min($arr); // 1array_reverse($arr); // [5, 4, 3, 2, 1]array_unique([1,1,2,3]); // [1, 2, 3]?>```text
### Работа с датой/временем
```php<?phpecho date("Y-m-d H:i:s"); // 2024-02-17 15:30:45echo time(); // 1708180245 (timestamp)echo strtotime("+1 week"); // timestamp через неделюecho date("d.m.Y", strtotime("2024-12-31"));?>```text
## WordPress контекст
### Hooks (actions и filters)
```php<?php// Action hookfunction my_custom_footer() { echo "<p>© 2024 Мой сайт</p>";}add_action('wp_footer', 'my_custom_footer');
// Filter hookfunction modify_title($title) { return $title . " | Мой сайт";}add_filter('the_title', 'modify_title');
// Удаление hookremove_action('wp_head', 'wp_generator');?>```text
### Кастомные функции темы
```php<?php// functions.php темы
// Регистрация менюfunction register_my_menus() { register_nav_menus([ 'header-menu' => 'Главное меню', 'footer-menu' => 'Меню в футере' ]);}add_action('init', 'register_my_menus');
// Поддержка миниатюрfunction theme_setup() { add_theme_support('post-thumbnails'); add_theme_support('title-tag'); add_theme_support('custom-logo');}add_action('after_setup_theme', 'theme_setup');
// Загрузка стилей и скриптовfunction enqueue_assets() { wp_enqueue_style('main-style', get_stylesheet_uri()); wp_enqueue_script('main-js', get_template_directory_uri() . '/js/main.js', [], '1.0', true);}add_action('wp_enqueue_scripts', 'enqueue_assets');?>```text
### Кастомные типы постов
```php<?phpfunction register_product_post_type() { $args = [ 'labels' => [ 'name' => 'Товары', 'singular_name' => 'Товар', 'add_new' => 'Добавить товар', 'add_new_item' => 'Добавить новый товар', 'edit_item' => 'Редактировать товар' ], 'public' => true, 'has_archive' => true, 'supports' => ['title', 'editor', 'thumbnail', 'excerpt'], 'menu_icon' => 'dashicons-products', 'rewrite' => ['slug' => 'products'] ];
register_post_type('product', $args);}add_action('init', 'register_product_post_type');?>```text
### Shortcodes
```php<?php// Простой shortcodefunction hello_shortcode() { return "Привет из shortcode!";}add_shortcode('hello', 'hello_shortcode');// Использование: [hello]
// Shortcode с параметрамиfunction button_shortcode($atts) { $atts = shortcode_atts([ 'text' => 'Нажми меня', 'url' => '#', 'color' => 'blue' ], $atts);
return '<a href="' . esc_url($atts['url']) . '" class="btn btn-' . $atts['color'] . '">' . esc_html($atts['text']) . '</a>';}add_shortcode('button', 'button_shortcode');// Использование: [button text="Купить" url="/cart" color="green"]
// Shortcode с контентомfunction box_shortcode($atts, $content = null) { return '<div class="box">' . do_shortcode($content) . '</div>';}add_shortcode('box', 'box_shortcode');// Использование: [box]Текст внутри бокса[/box]?>```text
## Практика
### Задание 1: Калькулятор
Создайте набор функций для математических операций:
```php<?phpfunction add($a, $b) { return $a + $b;}
function subtract($a, $b) { return $a - $b;}
function multiply($a, $b) { return $a * $b;}
function divide($a, $b) { if ($b == 0) { return "Ошибка: деление на ноль"; } return $a / $b;}
// Использованиеecho add(10, 5); // 15echo subtract(10, 5); // 5echo multiply(10, 5); // 50echo divide(10, 5); // 2?>```text
### Задание 2: Валидация email
Создайте функцию валидации email с различными проверками.
### Задание 3: Генератор slug
Создайте функцию, которая преобразует заголовок в URL-friendly slug.
```php<?phpfunction createSlug($text) { // Транслитерация $text = transliterate($text); // В нижний регистр $text = strtolower($text); // Замена пробелов на дефисы $text = str_replace(' ', '-', $text); // Удаление спецсимволов $text = preg_replace('/[^a-z0-9-]/', '', $text); // Удаление множественных дефисов $text = preg_replace('/-+/', '-', $text); // Убрать дефисы в начале и конце $text = trim($text, '-');
return $text;}
echo createSlug("Привет, Мир! Это тест."); // privet-mir-eto-test?>```text
### Задание 4: Фильтрация массива
Создайте функции для фильтрации массива по различным критериям.
### Задание 5: WordPress шорткод
Создайте свой shortcode для WordPress с параметрами.
## Онлайн-редакторы
Тестируйте примеры:- **PHPSandbox**: https://phpsandbox.io/- **3v4l**: https://3v4l.org/
## Итоги
В этом уроке вы изучили:
✅ **Объявление функций** — синтаксис и параметры✅ **Type hints** — строгая типизация (PHP 7+)✅ **Область видимости** — global, static, local✅ **Передача параметров** — по значению и по ссылке✅ **Анонимные функции** — closures и стрелочные функции✅ **Рекурсия** — функции, вызывающие сами себя✅ **WordPress hooks** — actions и filters✅ **Shortcodes** — создание кастомных шорткодов
### Следующий шаг
Переходите к изучению массивов: [Массивы](/php/arrays/)
### Ключевые моменты
1. **Функции делают код переиспользуемым** — DRY принцип2. **Используйте type hints** — меньше ошибок3. **Именованные аргументы** — читабельность (PHP 8+)4. **Стрелочные функции** — короче код (PHP 7.4+)5. **WordPress hooks** — основа расширяемости WP
**Совет:** Пишите небольшие функции с одной ответственностью — они проще тестировать и поддерживать!
---
**Готовы двигаться дальше?** Переходите к следующему уроку: [Массивы](/php/arrays/)