← Назад к вопросам

Что такое инкапсуляция в PHP?

1.3 Junior🔥 201 комментариев
#PHP Core#ООП

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое инкапсуляция в PHP?

Инкапсуляция — это один из основных принципов ООП, который предполагает скрытие внутреннего состояния объекта и предоставление контролируемого доступа к нему через публичные методы.

Цель инкапсуляции

  • Скрытие деталей реализации — клиент не должен знать внутреннюю структуру
  • Контроль доступа — валидация данных при изменении состояния
  • Независимость реализации — возможность менять внутреннюю логику без влияния на клиентов

Уровни доступа в PHP

class User {
    // Публичное — доступно везде
    public string $username;
    
    // Защищенное — доступно в классе и подклассах
    protected string $email;
    
    // Приватное — доступно только в этом классе
    private string $password;
    
    // Статичное и приватное
    private static int $userCount = 0;
}

Пример инкапсуляции

class BankAccount {
    private float $balance;
    
    public function __construct(float $initialBalance) {
        if ($initialBalance < 0) {
            throw new InvalidArgumentException('Balance cannot be negative');
        }
        $this->balance = $initialBalance;
    }
    
    // Получение значения
    public function getBalance(): float {
        return $this->balance;
    }
    
    // Установка с валидацией
    public function deposit(float $amount): void {
        if ($amount <= 0) {
            throw new InvalidArgumentException('Amount must be positive');
        }
        $this->balance += $amount;
    }
    
    public function withdraw(float $amount): void {
        if ($amount > $this->balance) {
            throw new InsufficientFundsException('Not enough funds');
        }
        $this->balance -= $amount;
    }
    
    // Приватный метод (не доступен снаружи)
    private function logTransaction(string $type, float $amount): void {
        // Внутреннее логирование
    }
}

// Использование
$account = new BankAccount(1000);
$account->deposit(500); // OK
$account->deposit(-100); // Exception: Amount must be positive
echo $account->getBalance(); // 1500

Getters и Setters

class Product {
    private string $name;
    private float $price;
    
    public function getName(): string {
        return $this->name;
    }
    
    public function setName(string $name): void {
        if (strlen($name) < 3) {
            throw new InvalidArgumentException('Name too short');
        }
        $this->name = $name;
    }
    
    public function getPrice(): float {
        return $this->price;
    }
    
    public function setPrice(float $price): void {
        if ($price < 0) {
            throw new InvalidArgumentException('Price cannot be negative');
        }
        $this->price = $price;
    }
}

Свойства с типизацией (PHP 7.4+)

class Employee {
    // Типизированные приватные свойства
    private int $id;
    private string $name;
    private float $salary;
    
    public function __construct(int $id, string $name, float $salary) {
        $this->id = $id;
        $this->name = $name;
        $this->setSalary($salary); // Используем сеттер для валидации
    }
    
    public function getId(): int {
        return $this->id;
    }
    
    public function getName(): string {
        return $this->name;
    }
    
    public function getSalary(): float {
        return $this->salary;
    }
    
    public function setSalary(float $salary): void {
        if ($salary < 0) {
            throw new InvalidArgumentException('Salary must be positive');
        }
        $this->salary = $salary;
    }
}

Инкапсуляция коллекций

class ShoppingCart {
    private array $items = [];
    
    // Добавление товара с валидацией
    public function addItem(string $productId, int $quantity): void {
        if ($quantity <= 0) {
            throw new InvalidArgumentException('Quantity must be positive');
        }
        $this->items[$productId] = ($this->items[$productId] ?? 0) + $quantity;
    }
    
    // Получение копии коллекции (не оригинал)
    public function getItems(): array {
        return $this->items;
    }
    
    // Работа с элементами только через методы
    public function removeItem(string $productId): void {
        unset($this->items[$productId]);
    }
    
    public function clear(): void {
        $this->items = [];
    }
}

$cart = new ShoppingCart();
$cart->addItem('product1', 2);
$items = $cart->getItems();
// Если изменить $items, это не повлияет на исходный массив

Protected для наследования

abstract class Animal {
    // Защищенное свойство доступно подклассам
    protected string $name;
    protected int $age;
    
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
    
    // Защищенный метод
    protected function getDescription(): string {
        return "{$this->name} ({$this->age} years)";
    }
    
    // Публичный метод
    public function introduce(): void {
        echo $this->getDescription();
    }
}

class Dog extends Animal {
    public function bark(): void {
        echo "{$this->name} says: Woof!\n"; // Доступ к protected свойству
    }
}

$dog = new Dog("Rex", 3);
$dog->introduce(); // Rex (3 years)
$dog->bark(); // Rex says: Woof!
// $dog->getDescription(); // Error: protected method

Readonly свойства (PHP 8.1+)

class Configuration {
    public readonly string $apiKey;
    public readonly int $timeout;
    
    public function __construct(string $apiKey, int $timeout) {
        $this->apiKey = $apiKey;
        $this->timeout = $timeout;
    }
    
    // Попытка изменить приведет к ошибке
}

$config = new Configuration('secret123', 30);
// $config->apiKey = 'new'; // Error: Cannot modify readonly property

Преимущества инкапсуляции

  • Контроль целостности — валидация при каждом изменении
  • Гибкость — можно менять реализацию без влияния на API
  • Безопасность — защита от неправильного использования
  • Тестируемость — легче тестировать с контролируемым состоянием

Антипаттерны

// Плохо — прямой доступ к свойствам
class BadUser {
    public $password; // Не валидируется
}

$user = new BadUser();
$user->password = ''; // Принимается, хотя неправильно

// Хорошо — через методы с валидацией
class GoodUser {
    private string $password;
    
    public function setPassword(string $password): void {
        if (strlen($password) < 8) {
            throw new InvalidArgumentException('Password too weak');
        }
        $this->password = password_hash($password, PASSWORD_BCRYPT);
    }
}

Заключение

Инкапсуляция в PHP достигается использованием private/protected модификаторов доступа и предоставлением контролируемого доступа через публичные методы (getters/setters). Это основной механизм для создания надежных и безопасных классов.

Что такое инкапсуляция в PHP? | PrepBro