PHP: полный мануал с примерами, функциями и ООП
Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Дерево руководства
Глава 72 · От простой записи к диагностике
stdClass и неполный объект: простые записи и диагностика восстановления
Создание, преобразование и ограничения стандартных объектов PHP, включая __PHP_Incomplete_Class.
stdClass: простая запись с полями без собственного класса
Пустая запись получает свои поля
stdClass удобен для простой записи, у которой пока нет собственных методов.
- 1new stdClass()↓
Создаётся пустой объект.
- 2$product->sku = 'A-10'↓
Добавляется поле с артикулом.
- 3$product->name = 'Книга'↓
Добавляется поле с названием.
- 4echo $product->name
Чтение возвращает Книга.
Модель не проверяет схему и допустимые имена. stdClass не является общим родителем всех PHP-объектов.
API прислал запись с артикулом и названием. Если пока не нужны методы и строгая доменная модель, можно представить её простым объектом stdClass. У класса нет своих методов и заранее объявленных свойств. new stdClass() создаёт пустую запись, а стрелочка -> обращается к полю. Динамические свойства здесь разрешены без дополнительного атрибута.
- new stdClass() → пустой объект
- $product->sku = "tea" → поле sku
- $product->title = "Чай" → поле title
- Чтение через -> возвращает сохранённое значение
<?php
declare(strict_types=1);
$product = new stdClass();
$product->sku = 'tea';
$product->title = 'Чай';
echo 'Карточка ', $product->sku, ': ', $product->title, "\n";
echo json_encode($product, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), "\n";
Ожидаемый результат
Карточка tea: Чай
{"sku":"tea","title":"Чай"}
stdClass — встроенный простой класс с разрешёнными динамическими свойствами. Он удобен записи без собственного поведения. Собственный Product с проверяющим конструктором нужен, когда важно поддерживать правила состояния; stdClass таких правил не добавляет.
<?php
declare(strict_types=1);
$product = json_decode('{"sku":"tea","stock":0}', false, 512, JSON_THROW_ON_ERROR);
if (!$product instanceof stdClass || !isset($product->sku) || !property_exists($product, 'stock')) {
throw new UnexpectedValueException('Нужна запись товара с остатком');
}
echo 'Артикул: ', $product->sku, "\n";
echo 'Остаток: ', $product->stock, " уп.\n";
Ожидаемый результат
Артикул: tea
Остаток: 0 уп.
false во втором аргументе json_decode просит объекты для JSON-объектов; массив JSON остаётся массивом. property_exists проверяет поле независимо от его null/нулевого значения. Для произвольного внешнего ответа далее проверяйте типы каждого поля; здесь схема фикстуры известна.
<?php
$record = (object) ['order-id' => 42, 1 => 'Первый'];
echo $record->{'order-id'}, "\n";
echo $record->{'1'}, "\n";
Ожидаемый результат
42
Первый
Фигурные скобки после стрелочки разрешают имя свойства как выражение. У stdClass бывают имена, которые нельзя записать обычным идентификатором. Для таких входных данных массив иногда удобнее.
stdClass не является общим предком всех объектов PHP. Собственный class Product сам по себе не наследует его. Наследовать stdClass явно можно, и динамические свойства будут разрешены, но не делайте это только ради подавления опечаток. Также stdClass могут возвращать mysqli_fetch_object и PDOStatement::fetchObject; конкретный результат и безопасность SQL рассматриваются в их категориях.
<?php
declare(strict_types=1);
class Product { public string $title = 'Чай'; }
function productLabel(Product $product): string { return 'Товар: ' . $product->title; }
$product = new Product();
echo productLabel($product), "\n";
echo $product instanceof stdClass ? "Это свободная запись stdClass\n" : "Это собственный Product с отдельным договором\n";
Ожидаемый результат
Товар: Чай
Это собственный Product с отдельным договором
Product и stdClass — разные классы. Общий тип object принимает оба, а тип stdClass не означает «любой объект». is_object годится широкой проверке формы, но не доказывает наличие нужных методов и полей.
__PHP_Incomplete_Class: данные восстановлены без доступного класса
При чтении старого локального снимка может оказаться, что определения класса больше нет или его восстановление запрещено. Не передавайте такой результат обычному сервису как готовую сущность. Сначала диагностируйте исходное имя, затем напишите контролируемую миграцию выбранных данных в новый проверенный класс.
Сохранённая PHP-строка содержит имя класса. Если класс неизвестен после автозагрузки или запрещён allowed_classes, unserialize может создать __PHP_Incomplete_Class. Это диагностический объект с сохранёнными полями и служебным именем исходного класса, а не рабочая замена его методов. Не продолжайте обработку заказа так, будто модель полностью восстановлена.
- В строке указан SavedRecord
- Класс недоступен или запрещён allowed_classes
- Создан __PHP_Incomplete_Class
- Диагностика: проверить автозагрузку, разрешённые типы и миграцию снимка
<?php
class SavedRecord { public string $sku = 'A-10'; }
$payload = serialize(new SavedRecord());
$restored = unserialize($payload, ['allowed_classes' => false]);
echo get_class($restored), "\n";
echo "Восстановлены поля, но методы SavedRecord недоступны\n";
$fields = (array) $restored;
echo $fields['__PHP_Incomplete_Class_Name'], ':', $fields['sku'], "\n";
Ожидаемый результат
__PHP_Incomplete_Class
Восстановлены поля, но методы SavedRecord недоступны
SavedRecord:A-10
allowed_classes=false запрещает создание исходного класса. PHP сохраняет доступное представление как __PHP_Incomplete_Class с именем исходного типа, но это не готовый SavedRecord. Пример использует только собственный локальный serialize; не подавайте внешнюю строку в unserialize даже ради этой диагностики.
<?php
$payload = 'O:13:"MissingRecord":0:{}';
$restored = unserialize($payload);
echo get_class($restored), "\n";
echo ((array) $restored)['__PHP_Incomplete_Class_Name'], "\n";
Ожидаемый результат
__PHP_Incomplete_Class
MissingRecord
Константная строка — учебная модель старой записи, а не образец ручной сборки сериализованных данных. В приложении проверьте Composer autoload и переименования классов до восстановления доверенных записей.
У этого класса нет собственных методов или свойств по умолчанию; поля появляются из снимка, дополнительно добавляется __PHP_Incomplete_Class_Name. С PHP 7.2 is_object возвращает true для такого значения; раньше возвращал false. С PHP 8.0 класс final. Поэтому одной проверки is_object недостаточно для проверки успешного восстановления ожидаемой модели.
Связанные темы: unserialize и формат данных, автозагрузка, JSON как внешний договор.
Источники и обсуждения
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


