Свойства с модификатором доступа public в PHP: подробное описание

Раздел: ООП в PHP -> Объектно-ориентированное программирование

Основные приемы работы с public свойствами в PHP

Основное и наиболее эффективное решение: объявление public свойства с явным указанием типа (начиная с PHP 7.4) и значением по умолчанию, если это уместно. Прямой доступ через оператор -> позволяет читать и изменять свойство без дополнительных методов. Такой подход подходит для простых данных, не требующих валидации или логики при установке.


<?php
class User {
    public string $name = 'Гость';
    public int $age;
}

$user = new User();
$user->name = 'Анна';  // запись
$user->age = 25;
echo $user->name . ', ' . $user->age;  // чтение
?>
  

классы в php файлы (определение классов в php-файлах)

Анна, 25

Php public var (public свойства класса в php)

Как объявить свойство без указания типа?

Используется ключевое слово var или public без типа. Ранний стиль (PHP 4) - var, но современная практика - применять public с типом.


<?php
class Product {
    public $price;  // без типа
    var $title;     // устаревший вариант
}
$p = new Product();
$p->price = 99.99;
?>
  

Php get set (геттеры и сеттеры в php)

Типичная ошибка: отсутствие типа может привести к передаче некорректных данных (например, строки вместо числа). Решение: с PHP 7.4+ рекомендуется всегда указывать тип. Исключение - случаи, когда свойство может принимать разные типы (тогда используется mixed или объединение типов).

Какие цели преследует такой вариант?

Обратная совместимость с кодом, написанным до PHP 7.4, или работа со свойствами, чей тип заранее не определён.

Как задать значение по умолчанию при объявлении?

Значение присваивается прямо в объявлении свойства. Допустимы константные выражения: числа, строки, массивы, null.


<?php
class Config {
    public string $siteName = 'Мой сайт';
    public int $port = 8080;
    public array $allowedRoles = ['admin', 'user'];
    public ?float $discount = null;
}
?>
  

Php method name (имя метода в php)

Проблема: нельзя использовать выражения, зависящие от времени выполнения (функции, new, ternary). Например, public $date = date('Y'); вызовет синтаксическую ошибку. Решение: инициализация в конструкторе.

Когда применяется?

Для фиксированных настроек, констант уровня класса или значений, не требующих вычислений при создании объекта.

Как получить доступ к public свойству внутри методов того же класса?

Используется $this->свойство. Конструкция $this ссылается на текущий объект.


<?php
class Counter {
    public int $count = 0;

    public function increment(): void {
        $this->count++;
    }

    public function show(): int {
        return $this->count;
    }
}
$c = new Counter();
$c->increment();
echo $c->show();
?>
  
1

Ошибка новичков: попытка обратиться к свойству без $this (например, $count++ внутри метода). Это создаёт локальную переменную, а не изменяет свойство объекта. Решение: всегда использовать $this-> для обращения к свойствам/методам текущего объекта.

Как изменить public свойство извне класса?

Прямое присваивание через оператор -> на экземпляре объекта.


<?php
class Point {
    public float $x = 0.0;
    public float $y = 0.0;
}
$p = new Point();
$p->x = 10.5;
$p->y = -3.2;
echo "x={$p->x}, y={$p->y}";
?>
  
x=10.5, y=-3.2

Риск: отсутствие контроля над присваиваемым значением. Если позже потребуется добавить валидацию, придётся заменять прямое свойство на геттер/сеттер, что сломает внешний код. Решение: изначально использовать приватные свойства с публичными методами доступа, если есть вероятность изменения логики.

Цель такого подхода?

Максимальная простота и производительность. Используется для данных, которые не требуют побочных эффектов при изменении (например, DTO, конфиги, простые структуры).

Как наследуются public свойства?

Public свойства доступны в дочерних классах напрямую и могут быть переопределены (значение по умолчанию или тип).


<?php
class Animal {
    public string $sound = '...';
}
class Dog extends Animal {
    // переопределяем значение
    public string $sound = 'Woof';
}
$dog = new Dog();
echo $dog->sound;
?>
  
Woof

Нюанс: при переопределении тип свойства в дочернем классе должен быть совместим с родительским (или отсутствовать). С PHP 7.4 можно сузить тип? Нет, ковариантность типов не поддерживается для свойств. Тип должен быть таким же или более общим (на практике чаще оставляют тот же). Решение: при необходимости изменить тип - пересмотреть архитектуру или не переопределять свойство, а использовать методы.

Как работают public статические свойства?

Статические public свойства принадлежат классу, а не объекту. Доступ через ClassName::$property или $object::$property.


<?php
class MathUtils {
    public static float $pi = 3.14159;
}
echo MathUtils::$pi;
?>
  
3.14159

Ошибка: попытка обратиться к статическому свойству через $this-> внутри метода объекта. Это вызовет ошибку, так как $this не определён в статическом контексте. Решение: использовать self::$property внутри класса или ClassName::$property снаружи.

Когда применяется?

Для общих констант (хотя лучше const), счётчиков экземпляров, разделяемых ресурсов.

Как использовать типизированные public свойства (PHP 7.4+)?

Тип указывается перед именем свойства. Поддерживаются скалярные типы, классы, интерфейсы, массивы, callable, mixed и т.д. Начиная с PHP 7.4 свойства могут быть объявлены с типом и без значения по умолчанию (тогда они неинициализированы, но при попытке чтения до присвоения - ошибка).


<?php
class Order {
    public int $id;
    public ?DateTimeImmutable $createdAt = null;
    public array $items = [];
}
$order = new Order();
$order->id = 1;
$order->createdAt = new DateTimeImmutable();
var_dump($order);
?>
  
object(Order)#1 (3) { ["id"]=> int(1) ["createdAt"]=> object(DateTimeImmutable)#2 (0) { } ["items"]=> array(0) { } }

Проблема: если свойство объявлено с типом, но без значения по умолчанию, и его не инициализировать в конструкторе - при попытке чтения до присвоения выбрасывается TypeError. Решение: всегда инициализировать такие свойства в конструкторе или присваивать значение сразу при создании объекта.

Какая цель?

Повышение надёжности кода - PHP автоматически проверяет соответствие типа при присвоении. Исключаются случайные несоответствия.

Как сделать public свойство неизменяемым после инициализации (readonly)?

В PHP 8.1+ используется модификатор readonly вместе с public. Такое свойство можно установить только один раз (в конструкторе или при объявлении).


<?php
class User {
    public readonly string $username;

    public function __construct(string $username) {
        $this->username = $username;
    }
}
$u = new User('ivan');
echo $u->username;
// $u->username = 'new'; // Ошибка: cannot modify readonly property
?>
  

Ограничение: readonly свойство не может быть статическим; его тип обязан быть объявлен; объекты можно менять внутри (если свойство содержит объект, сам объект не заморожен). Рекомендация: для иммутабельных DTO использовать readonly в сочетании с конструктором.

Когда это нужно?

Для неизменяемых данных после создания объекта - идентификаторы, даты создания, конфигурационные значения.

Все эти варианты позволяют гибко управлять доступом к данным объекта, выбирая между простотой и контролем.

Расширенные примеры с public свойствами

Пример

<?php
// Пример 1: Комбинирование public свойств с конструктором и типизацией
class Book {
    public string $title;
    public string $author;
    public int $year;
    public float $price;

    public function __construct(string $title, string $author, int $year, float $price) {
        $this->title = $title;
        $this->author = $author;
        $this->year = $year;
        $this->price = $price;
    }
}
$book = new Book('PHP для начинающих', 'Иван Петров', 2024, 1500.00);
echo "{$book->title} ({$book->year}) - {$book->price} руб.";
?>
PHP для начинающих (2024) - 1500 руб.
Пример

<?php
// Пример 2: Public свойства и трейты
trait Timestampable {
    public DateTimeImmutable $createdAt;
    public ?DateTimeImmutable $updatedAt = null;
}

class Post {
    use Timestampable;
    public string $content;

    public function __construct(string $content) {
        $this->content = $content;
        $this->createdAt = new DateTimeImmutable();
    }
}
$post = new Post('Текст поста');
echo $post->createdAt->format('Y-m-d H:i:s');
?>
2025-04-05 12:30:00 (текущая дата)
Пример

<?php
// Пример 3: Public static свойство как счётчик экземпляров
class Event {
    public static int $counter = 0;
    public string $name;

    public function __construct(string $name) {
        $this->name = $name;
        self::$counter++;
    }
}
$e1 = new Event('Событие 1');
$e2 = new Event('Событие 2');
echo "Создано экземпляров: " . Event::$counter;
?>
Создано экземпляров: 2
Пример

<?php
// Пример 4: Public свойства с объединёнными типами (PHP 8.0+)
class Flexible {
    public int|string $id;
    public ?float $score = null;
}
$f = new Flexible();
$f->id = 123;
$f->score = 4.5;
echo $f->id . ' - ' . $f->score;
?>
123 - 4.5
Пример

<?php
// Пример 5: Public свойства в анонимных классах
$obj = new class {
    public string $message = 'Привет из анонимного класса!';
};
echo $obj->message;
?>
Привет из анонимного класса!
Пример

<?php
// Пример 6: Public свойства и Reflection (изменение через API)
class Secret {
    public string $data = 'конфиденциально';
}
$ref = new ReflectionProperty('Secret', 'data');
$ref->setAccessible(true); // для private, но public и так доступен
$obj = new Secret();
echo $ref->getValue($obj);
?>
конфиденциально
Пример

<?php
// Пример 7: Public свойства и сериализация (json)
class Car {
    public string $brand;
    public string $model;
    public int $year;

    public function __construct(string $brand, string $model, int $year) {
        $this->brand = $brand;
        $this->model = $model;
        $this->year = $year;
    }
}
$car = new Car('Toyota', 'Camry', 2022);
echo json_encode($car, JSON_UNESCAPED_UNICODE);
?>
{"brand":"Toyota","model":"Camry","year":2022}
Пример

<?php
// Пример 8: Массив объектов и изменение public свойств
class Task {
    public string $title;
    public bool $completed = false;
}
$tasks = [
    new Task(),
    new Task(),
];
$tasks[0]->title = 'Купить молоко';
$tasks[0]->completed = true;
$tasks[1]->title = 'Позвонить другу';
foreach ($tasks as $task) {
    echo "{$task->title}: " . ($task->completed ? 'выполнено' : 'не выполнено') . "\n";
}
?>
Купить молоко: выполнено
Позвонить другу: не выполнено

Примечание к примерам:

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

public свойства класса в PHP - comments

En
Php public var (php)