Два мира в одном языке: почему это важно?
Когда мы говорим о PHP, в голову сразу приходит классический объектно-ориентированный подход (ООП). Классы, наследование, инкапсуляция — это база, которую учат на всех курсах. Но есть и другая сторона медали — функциональный подход. И знаете что? PHP умеет и то, и другое, причем очень хорошо.
В этой статье мы не будем спорить, что лучше. Мы разберемся, когда и какой подход стоит использовать, чтобы ваш код был не только красивым, но и быстрым. Если вы пишете на PHP и хотите выйти за рамки "просто работает" — вам сюда.
Объектно-ориентированный PHP: классика, которая не устаревает
ООП в PHP — это про структуру и переиспользование. Вы создаете классы, которые описывают сущности вашего приложения: пользователь, заказ, товар. Каждый класс отвечает за свою зону ответственности.
Пример: работа с пользователем через ООП
Давайте посмотрим на типичный пример. Допустим, нам нужно создать пользователя и отправить ему приветственное письмо.
<?php
class User {
private string $name;
private string $email;
public function __construct(string $name, string $email) {
$this->name = $name;
$this->email = $email;
}
public function sendWelcomeEmail(): void {
$subject = "Добро пожаловать, {$this->name}!";
$message = "Привет, {$this->name}. Рады видеть вас на нашем сайте.";
mail($this->email, $subject, $message);
}
public function getName(): string {
return $this->name;
}
}
$user = new User("Иван", "ivan@example.com");
$user->sendWelcomeEmail();
echo "Письмо отправлено пользователю: " . $user->getName();
?>
Здесь все логично: данные (имя, email) и методы (отправка письма) находятся в одном месте. Это удобно, когда у вас много разных операций с одной сущностью.
Плюсы ООП в PHP
- Читаемость: код разбит на логические блоки, легко найти нужный метод.
- Наследование: можно создать базовый класс и расширять его.
- Инкапсуляция: данные защищены от случайного изменения (private/protected).
- Полиморфизм: один интерфейс — разная реализация.
Минусы ООП
- Избыточность: для простой задачи (например, отформатировать строку) писать класс — это оверкилл.
- Состояние: объекты хранят состояние, что может привести к багам, если не следить за мутациями.
- Память: каждый объект занимает больше памяти, чем простая функция.
Функциональный PHP: минимализм и чистота
Функциональное программирование в PHP — это не просто "написать функцию". Это философия, где функции — это главные герои. Они не имеют побочных эффектов, не меняют глобальное состояние и всегда возвращают предсказуемый результат.
Пример: та же задача, но функционально
Давайте решим ту же задачу — создание пользователя и отправка письма — но без классов.
<?php
function createUser(string $name, string $email): array {
return ['name' => $name, 'email' => $email];
}
function sendWelcomeEmail(array $user): void {
$subject = "Добро пожаловать, {$user['name']}!";
$message = "Привет, {$user['name']}. Рады видеть вас на нашем сайте.";
mail($user['email'], $subject, $message);
}
function getUserName(array $user): string {
return $user['name'];
}
$user = createUser("Иван", "ivan@example.com");
sendWelcomeEmail($user);
echo "Письмо отправлено пользователю: " . getUserName($user);
?>
Выглядит проще? Да. Но здесь нет инкапсуляции — данные просто массив. Зато каждая функция делает только одно действие и ничего не знает о "внешнем мире".
Продвинутый функциональный подход: замыкания и функции высшего порядка
PHP поддерживает анонимные функции (замыкания) и функции, которые принимают другие функции как аргументы. Это мощный инструмент.
<?php
$users = [
['name' => 'Иван', 'age' => 25],
['name' => 'Мария', 'age' => 30],
['name' => 'Петр', 'age' => 17],
];
// Фильтрация: только совершеннолетние
$adults = array_filter($users, function($user) {
return $user['age'] >= 18;
});
// Извлечение имен
$names = array_map(function($user) {
return $user['name'];
}, $adults);
print_r($names); // ['Иван', 'Мария']
?>
Обратите внимание: мы не создавали ни одного класса, но код читается как инструкция: "взять массив, отфильтровать, преобразовать". Это и есть функциональный стиль.
Плюсы функционального подхода в PHP
- Простота: меньше кода, меньше магии.
- Предсказуемость: функция всегда возвращает одно и то же для одних и тех же входных данных.
- Тестируемость: легко тестировать изолированные функции.
- Производительность: меньше накладных расходов на объекты.
Минусы функционального подхода
- Сложность в больших проектах: когда у вас 100 функций, сложно понять, какая за что отвечает.
- Нет четкой структуры: легко скатиться в "спагетти-код".
- Ограничения: не все задачи можно элегантно решить без состояния.
Когда что использовать? Практические рекомендации
Спойлер: вам не нужно выбирать что-то одно. Лучшие проекты на PHP используют гибридный подход. Вот примерные правила:
ООП — когда:
- У вас сложная бизнес-логика с множеством взаимосвязанных сущностей (например, интернет-магазин: корзина, заказ, товар, скидка).
- Вы работаете в команде, где важна читаемость и поддержка кода.
- Используете фреймворки (Laravel, Symfony) — они построены на ООП.
- Нужно управлять состоянием (например, соединение с БД).
Функциональный подход — когда:
- У вас простая задача: обработка строк, фильтрация массивов, математические вычисления.
- Вы пишете утилиты или хелперы.
- Нужна высокая производительность (например, обработка большого массива данных).
- Вы хотите