Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

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

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 168 · После BSON, Query и простых обновлений

MongoDB: MinKey, MaxKey и миграция DBPointer, Symbol, Undefined

Служебные границы, точная проверка BSON-типа и постепенная миграция старых ссылок, статусов и неизвестных значений с видимым результатом.

Понять тип перед исправлением данных

После обновления старой MongoDB-интеграции контакты исчезли из выборки, а импорт показал непонятные Symbol и DBPointer. Здесь научимся увидеть реальные типы, отделить служебные границы MinKey/MaxKey от пользовательских значений и перевести старые записи в понятную современную схему. Результат каждой программы — таблица: какие документы выбраны, какой у них тип и что изменилось.

Два маршрута одной задачи
  1. Служебная граница → MinKey/MaxKey → правильное чтение диапазона и типизированный обмен
  2. Старый экспорт → имя BSON-типа → явное правило преобразования → проверенная новая запись
  3. Неизвестное значение или маршрут → отдельный отказ → соседние данные остаются неизменными

Представьте архив с подписями на папках. Две подписи могут выглядеть одинаково, но одна обозначает документ, другая — ссылку на документ. BSON-тип похож на такую метку смысла. Аналогия помогает различать представления; база не хранит физические папки, а тип не заменяет договорённости вашего сервиса.

$lower = new MongoDB\BSON\MinKey();
$upper = new MongoDB\BSON\MaxKey();
echo json_encode($lower, JSON_THROW_ON_ERROR); // {"$minKey":1}
echo json_encode($upper, JSON_THROW_ON_ERROR); // {"$maxKey":1}

Знак $ начинает имя переменной, = сохраняет значение справа, new создаёт объект класса. Пустые скобки означают отсутствие аргументов. Полное имя MongoDB\BSON\... принадлежит расширению mongodb. json_encode превращает объект в типизированный текст через JsonSerializable; echo выводит полученную строку. Эти две строки не подключаются к базе. Ниже полные программы выполняют запись и запросы.

Для спокойного чтения пригодятся переменные, массивы, параметры и return, Manager, Query и BulkWrite. Текущие BSON-типы и новые специальные типы — разные темы: ObjectId и обычные BSON-значения.

Границы, старые значения и отсутствие поля

Что встретилосьЧто означаетЧто делать
MinKey / MaxKeyКрайние служебные BSON-значенияЧитать как границы, не как цену или SQL MIN/MAX
DBPointerУстаревшая ссылка namespace + ObjectIdПроверить маршрут и клиента; перейти к явному ID
SymbolУстаревший тип со строковым текстомПроверить допустимость текста; сохранить обычную строку
UndefinedУстаревшее отдельное BSON-значениеНайти по типу; выбрать удаление ключа либо null
nullКлюч есть, значение явно nullИспользовать только если такой смысл принят в схеме
missingКлюча в документе нетПроверять $exists; не выдавать за пустую строку
"" / "undefined"Два обычных строковых значенияНе путать внешний вид и реальный тип

У классов DBPointer, Symbol и Undefined нет публичного конструктора. Они появляются при декодировании старых BSON-данных. В учебном архиве мы явно восстанавливаем небольшой старый fixture через Document::fromJSON, чтобы программа была воспроизводимой. Новая прикладная схема эти типы не создаёт.

Запустить восемь самостоятельных программ

Восемь самостоятельных архивов рассчитаны на PHP CLI 8.4+ x64, ext-mongodb 2.5+ и отдельный MongoDB Community 8.0+. Пакет проверяется в PHP 8.5.11 / mongodb 2.5.5 / MongoDB 8.0.34. Composer не нужен. README содержит установку расширения, проверку php.ini и способ запуска отдельного mongod на loopback.

$env:PHPMAN_MONGODB_URI='mongodb://127.0.0.1:27075/?directConnection=true&retryWrites=false'
$env:PHPMAN_MONGODB_DATABASE='php_manual_lab'
php example.php

Это команды PowerShell из распакованного каталога. example.php и sv128-helper.php должны лежать рядом. Каждый запуск создаёт ровно одну собственную коллекцию mongodb128_special_ со случайной частью, ограничивает чтение и удаляет только своё точное имя в finally. Затем проверяется отсутствие коллекции. База пользователя и другие коллекции не изменяются.

Увидеть MinKey и MaxKey среди обычных значений

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

Исходные данные

Пять документов: служебные нижняя и верхняя границы, null, число 20 и строка A. Поле v хранит значение, label — понятную подпись, _id — номер учебной строки.

Путь данных
  1. PHP: new MinKey() и new MaxKey() создают два разных BSON-объекта без аргументов
  2. MongoDB: BulkWrite сохраняет значения; sort по v располагает их в порядке BSON
  3. Человек: project добавляет имя типа, и HTML показывает нижнюю границу первой, верхнюю последней

Минимальный полезный вызов

$lower = new MongoDB\BSON\MinKey();
$upper = new MongoDB\BSON\MaxKey();
$filter = ['v' => ['$type' => 'minKey']]; // найти именно маркер
// В базе сортировка v: MinKey, null, 20, 'A', MaxKey.

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

Поле v означаетBSON-типID
нижняя границаminKey5
не заданоnull4
числоint3
текстstring2
верхняя границаmaxKey1

Как это работает

MinKey означает значение, которое находится раньше остальных BSON-значений в порядке сравнения. MaxKey — значение после остальных. Это отдельные BSON-типы; они не вычисляют минимум/максимум набора и не равны PHP_INT_MIN/PHP_INT_MAX.

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

$sort выполняется сервером. Поле _id является вторым ключом сортировки для определённого порядка при совпадении v. $limit ограничивает результат пятью строками. $project оставляет нужные столбцы и вычисляет $type; в PHP не загружается вся коллекция для последующей сортировки.

Отдельные выборки по $type: minKey и $type: maxKey находят именно границы. Так можно различить служебную запись и обычное число в диагностическом инструменте. Учебный порядок пяти типов не является перечислением всех BSON-типов.

Границы и ошибки

MinKey/MaxKey чаще нужны при чтении служебных границ и диагностике, чем в документах каталога. Не добавляйте их вместо отсутствующей цены. Демонстрация не создаёт индекс и не обещает ускорение запроса. Массивы и collation имеют дополнительные правила сравнения; здесь только заданные скалярные значения.

Полная самостоятельная программа и архив
Увидеть MinKey и MaxKey среди обычных значенийСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
sv128Insert($manager,$namespace,[['_id'=>1,'label'=>'верхняя граница','v'=>new MongoDB\BSON\MaxKey],['_id'=>2,'label'=>'текст','v'=>'A'],['_id'=>3,'label'=>'число','v'=>20],['_id'=>4,'label'=>'не задано','v'=>null],['_id'=>5,'label'=>'нижняя граница','v'=>new MongoDB\BSON\MinKey]]);
$sorted=sv128Aggregate($manager,$database,$collection,[['$sort'=>['v'=>1,'_id'=>1]],['$limit'=>5],['$project'=>['_id'=>1,'label'=>1,'type'=>['$type'=>'$v']]]]);
$rows=[];foreach($sorted as $doc){$rows[]=[$doc['label'],$doc['type'],$doc['_id']];}
$min=sv128Read($manager,$namespace,['v'=>['$type'=>'minKey']],['_id'=>1],1);
$max=sv128Read($manager,$namespace,['v'=>['$type'=>'maxKey']],['_id'=>1],1);
$checks=['database_sort_order'=>array_column($sorted,'_id')===[5,4,3,2,1],'explicit_types'=>array_column($sorted,'type')===['minKey','null','int','string','maxKey'],'minimum_selected_by_type'=>array_column($min,'_id')===[5],'maximum_selected_by_type'=>array_column($max,'_id')===[1]];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-sentinel-order', ['Поле v означает', 'BSON-тип', 'ID'], $rows, $checks, $runtime);
echo 'mongodb128-special-sentinel-order: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-sentinel-order: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Замените число 20 на -7. Оно останется между null и строкой. Затем добавьте обычное число 200 и увеличьте limit: обе числовые строки должны оказаться между null и A.

Отличить порядок BSON от фильтра по прикладному типу

Разработчик хочет получить допустимые числовые значения и ставит универсальные границы MinKey/MaxKey. Проверим, почему такой диапазон не подтверждает, что поле вообще существует и содержит число.

Исходные данные

Шесть документов: MinKey, null, 20, A, MaxKey и документ без v. Все условия отправляются в MongoDB, а в отчёт возвращаются только выбранные _id.

Путь данных
  1. Универсальные границы: gte MinKey + lte MaxKey выбирают ID 1–6 на этом наборе
  2. Числовое условие: gte 0 выбирает числовую строку ID 3
  3. Контракт поля: type int + gte 0 явно требует здесь BSON int и неотрицательное значение

Минимальный полезный вызов

$filter = ['v' => ['$type' => 'int', '$gte' => 0]];
// В наборе ниже подходит только документ 3 с v=20.
// Границы MinKey/MaxKey не проверяют наличие или числовой тип v.

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

ЗапросВыбранные IDЧто это значит
От MinKey до MaxKey1, 2, 3, 4, 5, 6включает отсутствие поля
Числовое v >= 03сравнивается числовой тип
BSON int и v >= 03тип указан отдельно

Как это работает

Оператор $gte означает «больше или равно», $lte — «меньше или равно». Они записаны строковыми ключами PHP-массива в одинарных кавычках: PHP не должен подставить переменную вместо имени MongoDB-оператора.

MinKey/MaxKey являются особыми крайними границами. В MongoDB 8.0 на этом наборе их совместное условие пропускает все шесть документов, включая отсутствие v. Поэтому диапазон нельзя использовать как проверку заполненности формы.

Для обычных сравнений MongoDB ограничивает сравнение подходящими типами; числа разных числовых BSON-типов сравнимы. Из порядка сортировки нельзя сделать вывод, будто любой текст автоматически пройдёт условие v >= 0. Серверная выборка в отчёте это показывает.

Последний фильтр намеренно требует int. Если модель разрешает любые BSON-числа, выбирают псевдоним $type: number и отдельно проверяют допустимость значения по правилам приложения. Добавление типа — описание требования к данным, а не универсальный рецепт ускорения.

Границы и ошибки

Пример фиксирует наблюдаемое поведение MongoDB 8.0.34 на скалярных значениях. Для поля-массива query $type может совпасть по элементу. Чтобы проверять тип всего значения, применяют aggregation $type внутри $expr, как в уроке миграции. Производительность оценивают по реальному индексу и explain.

Полная самостоятельная программа и архив
Отличить порядок BSON от фильтра по прикладному типуСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
sv128Insert($manager,$namespace,[['_id'=>1,'v'=>new MongoDB\BSON\MinKey],['_id'=>2,'v'=>null],['_id'=>3,'v'=>20],['_id'=>4,'v'=>'A'],['_id'=>5,'v'=>new MongoDB\BSON\MaxKey],['_id'=>6]]);
$range=sv128Read($manager,$namespace,['v'=>['$gte'=>new MongoDB\BSON\MinKey,'$lte'=>new MongoDB\BSON\MaxKey]],['_id'=>1],6);
$numbers=sv128Read($manager,$namespace,['v'=>['$gte'=>0]],['_id'=>1],6);
$typed=sv128Read($manager,$namespace,['v'=>['$type'=>'int','$gte'=>0]],['_id'=>1],6);
$rows=[['От MinKey до MaxKey',implode(', ',array_column($range,'_id')),'включает отсутствие поля'],['Числовое v >= 0',implode(', ',array_column($numbers,'_id')),'сравнивается числовой тип'],['BSON int и v >= 0',implode(', ',array_column($typed,'_id')),'тип указан отдельно']];
$checks=['sentinel_range_is_not_validation'=>array_column($range,'_id')===[1,2,3,4,5,6],'numeric_comparison_is_type_bracketed'=>array_column($numbers,'_id')===[3],'explicit_integer_contract'=>array_column($typed,'_id')===[3],'maxkey_not_numeric_quantity'=>!in_array(5,array_column($numbers,'_id'),true)];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-sentinel-bounds', ['Запрос', 'Выбранные ID', 'Что это значит'], $rows, $checks, $runtime);
echo 'mongodb128-special-sentinel-bounds: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-sentinel-bounds: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Добавьте строку "20": универсальные границы её пропустят, числовой фильтр — нет. Для экрана каталога оставьте только нужные поля в projection и задайте сортировку/limit на сервере.

Практическая проблема: Что означают MinKey и MaxKey и почему сравнение со строкой ведёт себя иначе. Автор смешал порядок BSON-типов и обычный фильтр сравнения. Наш исходный пример сравнивает реальные выборки универсальных границ и конкретного числового типа. Обсуждение помогает увидеть задачу; правила текущей версии подтверждаются первичными источниками, код и объяснения здесь самостоятельные.

Передать служебные границы через функцию и типизированный JSON

Инструмент диагностики должен передать границы диапазона из одного слоя приложения в другой и экспортировать их, не превратив MinKey в строку "MinKey".

Исходные данные

Объект Bounds128 содержит lower типа MinKeyInterface и upper типа MaxKeyInterface. Две функции принимают и возвращают соответствующую границу. Неверная строка специально проверяется как ошибка входа.

Путь данных
  1. Аргумент: объект MinKey входит в lower-параметр sv128Lower
  2. Возврат: return отдаёт тот же объект для документа границ
  3. Хранение и обмен: MongoDB сохраняет BSON-типы; Canonical Extended JSON восстанавливает их через Document::fromJSON

Минимальный полезный вызов

function lowerBoundary(MongoDB\BSON\MinKeyInterface $value): MongoDB\BSON\MinKeyInterface {
    return $value;
}
$boundary = lowerBoundary(new MongoDB\BSON\MinKey());
echo json_encode($boundary, JSON_THROW_ON_ERROR); // {"$minKey":1}

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

Действие / полеПредставлениеРезультат
lower{"$minKey":1}MinKey
upper{"$maxKey":1}MaxKey
Обычный json_decodearrayмассив представления
Неподходящая строкаTypeErrorфункция не приняла границу

Как это работает

Интерфейс — типовой договор. MinKeyInterface и MaxKeyInterface не объявляют методов: они позволяют обозначить ожидаемый вид BSON-значения в параметре, возвращаемом значении или свойстве. Указать интерфейс — не значит вызвать его конструктор.

У функции sv128Lower переменная $value является параметром. Переданный объект становится её значением; return $value возвращает объект в место вызова. Объявление : MinKeyInterface проверяет тип результата. Аналогично работает верхняя граница.

jsonSerialize() возвращает PHP-структуру, например ["$minKey" => 1]. json_encode превращает её в текст {"$minKey":1}; при кодировании самого объекта JsonSerializable вызывается автоматически. Это не запрос в базу.

Обычный json_decode(..., true) возвращает массив с ключом $minKey. Он не создаёт MinKey. Document::fromJSON понимает Extended JSON и восстанавливает BSON-тип. Ошибочная строка в интерфейсном параметре вызывает TypeError до выполнения тела функции.

Границы и ошибки

Маркерный интерфейс полезен внутри PHP-контракта. Самостоятельная реализация пустого интерфейса ещё не доказывает, что драйвер умеет записывать пользовательский объект как BSON MinKey/MaxKey; в примере используются штатные final-классы. Тип границы не проверяет авторизацию, существование индекса или корректность бизнес-диапазона.

Параметры, свойства и договор интерфейса · Document::fromJSON и типизированный текст.

Полная самостоятельная программа и архив
Передать служебные границы через функцию и типизированный JSONСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
function sv128Lower(MongoDB\BSON\MinKeyInterface $value): MongoDB\BSON\MinKeyInterface {return $value;}
function sv128Upper(MongoDB\BSON\MaxKeyInterface $value): MongoDB\BSON\MaxKeyInterface {return $value;}
final class Bounds128 {
    public function __construct(public MongoDB\BSON\MinKeyInterface $lower,public MongoDB\BSON\MaxKeyInterface $upper) {}
}
$bounds=new Bounds128(sv128Lower(new MongoDB\BSON\MinKey),sv128Upper(new MongoDB\BSON\MaxKey));
sv128Insert($manager,$namespace,[['_id'=>1,'lower'=>$bounds->lower,'upper'=>$bounds->upper]]);
$stored=sv128Read($manager,$namespace,['_id'=>1],['_id'=>0,'lower'=>1,'upper'=>1],1)[0];
$lower=$stored['lower'];$upper=$stored['upper'];
$json=MongoDB\BSON\Document::fromPHP($stored)->toCanonicalExtendedJSON();$back=MongoDB\BSON\Document::fromJSON($json);
$plain=json_decode(json_encode($lower,JSON_THROW_ON_ERROR),true,512,JSON_THROW_ON_ERROR);
$badLower=false;$badUpper=false;
try{sv128Lower('MinKey');}catch(TypeError){$badLower=true;}
try{sv128Upper('MaxKey');}catch(TypeError){$badUpper=true;}
$rows=[['lower',json_encode($lower,JSON_THROW_ON_ERROR),'MinKey'],['upper',json_encode($upper,JSON_THROW_ON_ERROR),'MaxKey'],['Обычный json_decode',get_debug_type($plain),'массив представления'],['Неподходящая строка','TypeError','функция не приняла границу']];
$checks=['minimum_interface'=>$lower instanceof MongoDB\BSON\MinKeyInterface,'maximum_interface'=>$upper instanceof MongoDB\BSON\MaxKeyInterface,'min_serializer'=>$lower->jsonSerialize()===['$minKey'=>1],'max_serializer'=>$upper->jsonSerialize()===['$maxKey'=>1],'typed_min_roundtrip'=>$back->get('lower') instanceof MongoDB\BSON\MinKey,'typed_max_roundtrip'=>$back->get('upper') instanceof MongoDB\BSON\MaxKey,'plain_is_array'=>is_array($plain),'both_wrong_types_rejected'=>$badLower&&$badUpper];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-sentinel-contract', ['Действие / поле', 'Представление', 'Результат'], $rows, $checks, $runtime);
echo 'mongodb128-special-sentinel-contract: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-sentinel-contract: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Поменяйте местами lower и upper при создании Bounds128: типы должны запретить такую передачу. Для JSON-API отдельно опишите, понимает ли потребитель Extended JSON; не заменяйте объекты похожими строками.

Прочитать старый документ и показать тип каждого поля

Старый экспорт содержит непривычные BSON-типы. До исправления данных нужно увидеть, какие поля являются DBPointer, Symbol или Undefined, и отличить их от похожих строк.

Исходные данные

Шесть строк учебной коллекции: DBPointer на legacy.customers/ObjectId, Symbol published, Undefined, обычная строка published, null и отсутствие v. Старые значения восстановлены из явного Extended JSON только для воспроизводимого разбора.

Путь данных
  1. Экспорт: Document::fromJSON распознаёт $dbPointer, $symbol и $undefined
  2. Сервер: типизированные значения записываются; aggregation $type возвращает имя реального BSON-типа
  3. Инвентаризация: таблица отделяет symbol от string и undefined от null/missing

Минимальный полезный вызов

$document = MongoDB\BSON\Document::fromJSON('{"state":{"$symbol":"published"}}');
$state = $document->get('state');
echo get_debug_type($state); // MongoDB\BSON\Symbol
echo (string) $state;        // published; тип ещё не string в BSON

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

IDИсходный смыслТип самого поля
1старая ссылкаdbPointer
2старая меткаsymbol
3старое undefinedundefined
4обычная строкаstring
5nullnull
6поле отсутствуетmissing

Как это работает

BSON-типы DBPointer, Symbol и Undefined устарели. Драйвер сохраняет классы для чтения старых данных. Это возможность разобраться с архивом, а не предложение проектировать новые поля такими типами.

Их конструкторы private: new MongoDB\BSON\Symbol() недоступен прикладному коду. В полной программе ожидаемый PHP Error перехватывается отдельно для трёх классов. Декодер BSON может создавать такие объекты при чтении.

Document::get возвращает BSON-значение по имени. Далее обычный Cursor также отдаёт соответствующие объекты. instanceof проверяет класс PHP, а aggregation $type показывает тип на сервере. Это две точки контроля одного пути данных.

Не ориентируйтесь на один только echo: Symbol published похож на обычную строку; Undefined выводится пустой строкой. DBPointer в ext-mongodb 2.5.5 имеет диагностический вид [namespace/ObjectId]. Для решения о миграции нужны тип и структура значения.

Границы и ошибки

Весь исходный fixture остаётся в тексте программы и архиве; после запуска удаляется только собственная учебная коллекция. Для настоящего архива сначала сохраняют исходный экспорт отдельно. Некорректный Extended JSON вызывает ошибку декодирования; обход private-конструкторов через reflection здесь не нужен.

Полная самостоятельная программа и архив
Прочитать старый документ и показать тип каждого поляСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
$legacy=MongoDB\BSON\Document::fromJSON('{"pointer":{"$dbPointer":{"$ref":"legacy.customers","$id":{"$oid":"507f1f77bcf86cd799439011"}}},"symbol":{"$symbol":"published"},"undefined":{"$undefined":true}}');
$pointer=$legacy->get('pointer');$symbol=$legacy->get('symbol');$undefined=$legacy->get('undefined');
sv128Insert($manager,$namespace,[['_id'=>1,'label'=>'старая ссылка','v'=>$pointer],['_id'=>2,'label'=>'старая метка','v'=>$symbol],['_id'=>3,'label'=>'старое undefined','v'=>$undefined],['_id'=>4,'label'=>'обычная строка','v'=>'published'],['_id'=>5,'label'=>'null','v'=>null],['_id'=>6,'label'=>'поле отсутствует']]);
$docs=sv128Aggregate($manager,$database,$collection,[['$sort'=>['_id'=>1]],['$limit'=>6],['$project'=>['_id'=>1,'label'=>1,'type'=>['$type'=>'$v']]]]);
$rows=[];foreach($docs as $doc){$rows[]=[$doc['_id'],$doc['label'],$doc['type']];}
$stored=sv128Read($manager,$namespace,['_id'=>['$in'=>[1,2,3]]],['_id'=>1,'v'=>1],3);
$blocked=0;foreach([MongoDB\BSON\DBPointer::class,MongoDB\BSON\Symbol::class,MongoDB\BSON\Undefined::class] as $class){try{new $class();}catch(Error){$blocked++;}}
$checks=['all_six_distinct_states'=>array_column($docs,'type')===['dbPointer','symbol','undefined','string','null','missing'],'pointer_restored'=>$stored[0]['v'] instanceof MongoDB\BSON\DBPointer,'symbol_restored'=>$stored[1]['v'] instanceof MongoDB\BSON\Symbol,'undefined_restored'=>$stored[2]['v'] instanceof MongoDB\BSON\Undefined,'private_constructors_blocked'=>$blocked===3,'pointer_string_observed'=>(string)$pointer==='[legacy.customers/507f1f77bcf86cd799439011]','symbol_string'=>(string)$symbol==='published','undefined_string_empty'=>(string)$undefined===''];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-legacy-inventory', ['ID', 'Исходный смысл', 'Тип самого поля'], $rows, $checks, $runtime);
echo 'mongodb128-special-legacy-inventory: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-legacy-inventory: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Добавьте обычную строку "undefined" рядом с BSON Undefined. В результате получите string и undefined: одинаковое слово в интерфейсе не означает одинаковый тип данных.

Разделить undefined, null, отсутствие и пустую строку

На странице контактов нужно различить «поле ещё не запрашивали», «значение явно не задано» и старое ошибочное undefined. Иначе счётчики и фильтры после обновления MongoDB меняют смысл.

Исходные данные

Пять состояний email: BSON Undefined, null, отсутствующий ключ, строка undefined и пустая строка. Отчёт показывает точные ID для шести отдельных условий.

Путь данных
  1. Данные: ID 1: undefined; 2: null; 3: ключа нет; 4: слово undefined; 5: пустая строка
  2. Фильтр: условия null, $type, $exists и точные строки выполняются отдельно
  3. Результат: null выбирает 2,3; специальный undefined выбирает только 1

Минимальный полезный вызов

$filter = ['email' => ['$type' => 'undefined']]; // именно BSON-тип 6
$nullOnly = ['email' => ['$type' => 'null']];    // именно BSON-тип 10
$missing = ['email' => ['$exists' => false]];   // поле отсутствует

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

УсловиеВыбранные ID
Равенство null2, 3
Тип undefined1
Тип null2
Поля нет3
Пустая строка5
Строка undefined4

Как это работает

Отсутствие поля означает, что ключа email нет в документе. null — ключ существует, значение явно null. BSON undefined — отдельный устаревший тип. Пустая строка и текст undefined являются обычными строками.

Начиная с MongoDB 8.0 равенство null больше не включает BSON undefined. В нашей скалярной выборке ["email" => null] возвращает ID 2 и 3. Поэтому старый совет искать undefined через null применять без версии нельзя.

Фильтр $type: null выбирает только настоящий null, $exists: false — отсутствие ключа, $type: undefined — старый тип. Условие с обычной строкой undefined находит ID 4, а строка "" — ID 5.

Undefined::jsonSerialize сохраняет тип через $undefined: true. Приведение Undefined к строке даёт "", но объект не становится null и не равен пустому строковому полю в BSON. Использовать это приведение для диагностики состояния нельзя.

Границы и ошибки

Фильтры здесь показаны для скалярного поля. Query $type может проверить элемент массива; array с undefined требует отдельной политики. Изменение MongoDB 8.0 затрагивает связанные равенства/$in и сопоставления $lookup; проверьте конкретный контракт интеграции, а не только экран.

Полная самостоятельная программа и архив
Разделить undefined, null, отсутствие и пустую строкуСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
$undefined=MongoDB\BSON\Document::fromJSON('{"v":{"$undefined":true}}')->get('v');
sv128Insert($manager,$namespace,[['_id'=>1,'email'=>$undefined],['_id'=>2,'email'=>null],['_id'=>3],['_id'=>4,'email'=>'undefined'],['_id'=>5,'email'=>'']]);
$filters=['Равенство null'=>['email'=>null],'Тип undefined'=>['email'=>['$type'=>'undefined']],'Тип null'=>['email'=>['$type'=>'null']],'Поля нет'=>['email'=>['$exists'=>false]],'Пустая строка'=>['email'=>''],'Строка undefined'=>['email'=>'undefined']];
$selected=[];$rows=[];
foreach($filters as $label=>$filter){$docs=sv128Read($manager,$namespace,$filter,['_id'=>1],5);$selected[$label]=array_column($docs,'_id');$rows[]=[$label,implode(', ',$selected[$label])];}
$serialized=$undefined->jsonSerialize();$encoded=json_decode(json_encode($undefined,JSON_THROW_ON_ERROR),true,512,JSON_THROW_ON_ERROR);
$checks=['mongo8_null_does_not_match_undefined'=>$selected['Равенство null']===[2,3],'undefined_only'=>$selected['Тип undefined']===[1],'null_only'=>$selected['Тип null']===[2],'missing_only'=>$selected['Поля нет']===[3],'empty_string_only'=>$selected['Пустая строка']===[5],'literal_string_only'=>$selected['Строка undefined']===[4],'undefined_serialization'=>$serialized===['$undefined'=>true]&&$encoded===$serialized,'empty_cast_is_not_null'=>(string)$undefined===''&&$undefined!==null];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-undefined-query', ['Условие', 'Выбранные ID'], $rows, $checks, $runtime);
echo 'mongodb128-special-undefined-query: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-undefined-query: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Для отчёта «адрес ещё не известен» выберите правило. Например, объедините только null и missing, оставив BSON undefined отдельной строкой ошибки качества данных. Это решение предметной области, а не автоматическое свойство PHP.

Практическая проблема: Как найти записи с настоящим BSON undefined. После ошибочного обновления появились значения undefined, которые инструменты показывали неоднозначно. Старые ответы нельзя переносить на MongoDB8 без учёта изменённого null-сравнения. Обсуждение помогает увидеть задачу; правила текущей версии подтверждаются первичными источниками, код и объяснения здесь самостоятельные.

Заменить undefined по явному правилу, сохранив соседние состояния

В известном поле email обнаружены старые undefined. Для одной категории контактов поле нужно убрать, для другой — оставить явный null. Соседние значения и строки трогать нельзя.

Исходные данные

ID 1 и 2 имеют Undefined. ID 3 уже null, ID 4 не имеет email, ID 5 содержит строку undefined. Политика для ID 1 — удалить ключ, для ID 2 — заменить значение на null.

Путь данных
  1. Проверка: точный _id + $expr с $type самого email == undefined
  2. Изменение: ID 1: $unset; ID 2: $set null; multi=false/upsert=false
  3. Контроль: ровно два изменения; соседние состояния сохранены; повторный unset совпал с 0 документами

Минимальный полезный вызов

$filter = ['_id' => 1,
    '$expr' => ['$eq' => [['$type' => '$email'], 'undefined']]];
$update = ['$unset' => ['email' => '']];
// Точный ID и проверка типа самого поля: после обновления поля email нет.

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

IDПравило для записиТип после изменения
1удалить неизвестное полеmissing
2сохранить явное nullnull
3не менятьnull
4не менятьmissing
5не менятьstring

Как это работает

$unset удаляет ключ; $set сохраняет ключ с новым значением. Эти результаты различаются: в таблице первый станет missing, второй null. Выберите политику до запуска изменений.

$expr позволяет использовать выражение aggregation в фильтре запроса. Внутренний $type получает само поле email. Поэтому условие не перепутает массив, внутри которого есть undefined, со скалярным undefined.

Точный _id ограничивает изменение выбранной записью. multi: false запрещает массовое обновление; upsert: false не создаёт новый документ при отсутствии совпадения. MatchedCount и ModifiedCount проверяют реальное действие сервера.

Повтор запуска операции для уже исправленного ID 1 не находит undefined и ничего не меняет. Это полезное свойство возобновляемой миграции, но его нужно подтверждать выбранным фильтром, а не считать автоматическим для любого update.

Границы и ошибки

Операции относятся к известному верхнему полю. Рекурсивная миграция массивов и вложенных объектов требует отдельного алгоритма. Учебный набор не изменяется конкурентно. Для рабочей базы нужны резерв, ограниченные партии и контроль версии/параллельных записей; атомарность одного документа не делает всю миграцию одной транзакцией.

Атомарное обновление и условие версии · Когда нужна общая транзакция.

Полная самостоятельная программа и архив
Заменить undefined по явному правилу, сохранив соседние состоянияСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
$undefined=MongoDB\BSON\Document::fromJSON('{"v":{"$undefined":true}}')->get('v');
sv128Insert($manager,$namespace,[['_id'=>1,'email'=>$undefined],['_id'=>2,'email'=>$undefined],['_id'=>3,'email'=>null],['_id'=>4],['_id'=>5,'email'=>'undefined']]);
$guard=['$expr'=>['$eq'=>[['$type'=>'$email'],'undefined']]];
$bulk=new MongoDB\Driver\BulkWrite;
$bulk->update(['_id'=>1]+$guard,['$unset'=>['email'=>'']],['multi'=>false,'upsert'=>false]);
$bulk->update(['_id'=>2]+$guard,['$set'=>['email'=>null]],['multi'=>false,'upsert'=>false]);
$write=$manager->executeBulkWrite($namespace,$bulk,['writeConcern'=>new MongoDB\Driver\WriteConcern(1,3000)]);
$after=sv128Aggregate($manager,$database,$collection,[['$sort'=>['_id'=>1]],['$limit'=>5],['$project'=>['_id'=>1,'type'=>['$type'=>'$email']]]]);
$policy=[1=>'удалить неизвестное поле',2=>'сохранить явное null',3=>'не менять',4=>'не менять',5=>'не менять'];
$rows=[];foreach($after as $doc){$rows[]=[$doc['_id'],$policy[$doc['_id']],$doc['type']];}
$repeat=new MongoDB\Driver\BulkWrite;$repeat->update(['_id'=>1]+$guard,['$unset'=>['email'=>'']],['multi'=>false,'upsert'=>false]);
$again=$manager->executeBulkWrite($namespace,$repeat,['writeConcern'=>new MongoDB\Driver\WriteConcern(1,3000)]);
$text=sv128Read($manager,$namespace,['_id'=>5],['_id'=>0,'email'=>1],1)[0]['email'];
$checks=['two_targeted_changes'=>$write->getMatchedCount()===2&&$write->getModifiedCount()===2,'explicit_new_states'=>array_column($after,'type')===['missing','null','null','missing','string'],'literal_unchanged'=>$text==='undefined','repeat_matches_nothing'=>$again->getMatchedCount()===0,'no_undefined_left'=>sv128Read($manager,$namespace,$guard,['_id'=>1],1)===[]];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-undefined-migrate', ['ID', 'Правило для записи', 'Тип после изменения'], $rows, $checks, $runtime);
echo 'mongodb128-special-undefined-migrate: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-undefined-migrate: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. Добавьте документ с email=[Undefined]. Фильтр типа самого поля должен его пропустить. Предложите отдельное правило для массива: удалить элемент или сохранить его место как null — это разные результаты.

Практическая проблема: Когда сохранять null, а когда не хранить ключ вообще. Разработчик выбирает модель необязательного поля. Удаление ключа и явный null имеют разный смысл; в нашей миграции это два явных правила, а не слепая замена всего пустого. Обсуждение помогает увидеть задачу; правила текущей версии подтверждаются первичными источниками, код и объяснения здесь самостоятельные.

Перенести старую метку Symbol в обычную строку

В архиве редакционной системы статус published записан как BSON Symbol. Современный интерфейс ждёт обычную строку с разрешённым статусом. Нужно сохранить текст и поменять именно тип.

Исходные данные

ID 1 содержит Symbol published, ID 2 уже содержит строку published. Canonical-экспорт и jsonSerialize помогают увидеть исходный тип перед преобразованием.

Путь данных
  1. Чтение: Cursor возвращает объект Symbol; (string) даёт published
  2. Проверка: текст входит в разрешённый набор draft/published; тип самого поля равен symbol
  3. Запись: только ID 1 получает строку; ID 2 остаётся строкой published

Минимальный полезный вызов

$text = (string) $oldSymbol; // например published
if (!in_array($text, ['draft', 'published'], true)) {
    throw new InvalidArgumentException('Неизвестный статус');
}
$update = ['$set' => ['state' => $text]]; // теперь BSON string

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

ШагЗначениеBSON-тип
До миграцииpublishedsymbol
Типизированный экспортpublishedsymbol
После миграцииpublishedstring
Соседняя записьpublishedstring

Как это работает

Symbol в этом уроке — старый BSON-тип. Он не имеет отношения к имени PHP-функции, переменной или современному PHP enum. Его строковое представление содержит сохранённый текст.

jsonSerialize возвращает структуру с $symbol. Она полезна для экспорта до преобразования: обычный вывод published скрыл бы отличие от соседней строки. Document::fromJSON восстанавливает Symbol из типизированного экспорта.

После проверки класса можно получить текст через (string)$symbol. Проверка допустимых статусов решает задачу приложения: ошибочный архивный текст не должен автоматически стать легальным статусом.

Фильтр сочетает _id и тип symbol. Сервер меняет только найденную строку; последующее чтение подтверждает string. При неизменяемом fixture мы заранее знаем значение. Реальная конкурентная миграция должна дополнительно защищать ожидаемую версию/исходное состояние, иначе type-only условие не заметит, что другой процесс заменил один Symbol другим.

Границы и ошибки

Не применяйте (string) ко всем неизвестным объектам в импорте. DBPointer и Undefined имеют другие значения строкового представления. При сохранении результата в HTML текст экранируется; статус как строка не становится безопасным HTML автоматически.

Атомарное обновление и условие версии · Когда нужна общая транзакция.

Полная самостоятельная программа и архив
Перенести старую метку Symbol в обычную строкуСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
$symbol=MongoDB\BSON\Document::fromJSON('{"v":{"$symbol":"published"}}')->get('v');
sv128Insert($manager,$namespace,[['_id'=>1,'state'=>$symbol],['_id'=>2,'state'=>'published']]);
$before=sv128Read($manager,$namespace,['_id'=>1],['_id'=>1,'state'=>1],1)[0]['state'];
$serialized=$before->jsonSerialize();$canonical=MongoDB\BSON\Document::fromPHP(['state'=>$before])->toCanonicalExtendedJSON();
$restored=MongoDB\BSON\Document::fromJSON($canonical)->get('state');
$value=(string)$before;if(!in_array($value,['draft','published'],true)){throw new RuntimeException('Unknown legacy state');}
$bulk=new MongoDB\Driver\BulkWrite;
$bulk->update(['_id'=>1,'$expr'=>['$eq'=>[['$type'=>'$state'],'symbol']]],['$set'=>['state'=>$value]],['multi'=>false,'upsert'=>false]);
$write=$manager->executeBulkWrite($namespace,$bulk,['writeConcern'=>new MongoDB\Driver\WriteConcern(1,3000)]);
$after=sv128Aggregate($manager,$database,$collection,[['$sort'=>['_id'=>1]],['$limit'=>2],['$project'=>['_id'=>1,'state'=>1,'type'=>['$type'=>'$state']]]]);
$rows=[['До миграции',(string)$before,'symbol'],['Типизированный экспорт',(string)$restored,'symbol'],['После миграции',$after[0]['state'],$after[0]['type']],['Соседняя запись',$after[1]['state'],$after[1]['type']]];
$checks=['read_symbol'=>$before instanceof MongoDB\BSON\Symbol,'serializer_keeps_marker'=>$serialized===['$symbol'=>'published'],'typed_export_preserves_symbol'=>$restored instanceof MongoDB\BSON\Symbol,'only_one_modified'=>$write->getMatchedCount()===1&&$write->getModifiedCount()===1,'explicit_string_conversion'=>$after[0]['type']==='string'&&$after[0]['state']==='published','neighbor_unchanged'=>$after[1]['type']==='string'&&$after[1]['state']==='published'];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-symbol-migrate', ['Шаг', 'Значение', 'BSON-тип'], $rows, $checks, $runtime);
echo 'mongodb128-special-symbol-migrate: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-symbol-migrate: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

Попробуйте изменить. В исходный Symbol подставьте archived. Добавьте его в список только если приложение действительно поддерживает такой статус; иначе сохраните отказ импорта для ручного разбора.

Заменить старую DBPointer-ссылку проверенным ObjectId

В старом заказе хранится DBPointer на клиента. Новая схема использует явный customer_id. Нужно прочитать ссылку, найти разрешённого клиента и не обращаться к произвольной коллекции, указанной в архиве.

Исходные данные

В одной учебной коллекции лежат клиент Анна и два заказа. ORDER-1 ссылается на разрешённое legacy.customers; ORDER-2 содержит outside.secrets. Обе ссылки используют один ObjectId, чтобы различие решения зависело от маршрута.

Путь данных
  1. Структура: jsonSerialize → $dbPointer → $ref и $id.$oid
  2. Разрешённый путь: legacy.customers отображается в точное имя собственной коллекции; читается один клиент
  3. Миграция: ORDER-1 получает customer_id и revision=2; ORDER-2 не меняется и не вызывает внешний запрос

Минимальный полезный вызов

$shape = $oldPointer->jsonSerialize()['$dbPointer'];
$route = $shape['$ref'];
$idText = $shape['$id']['$oid'];
// Сначала разрешённый маршрут и существование клиента; затем:
$customerId = new MongoDB\BSON\ObjectId($idText);

Этот короткий фрагмент выделяет текущую операцию. Полная программа ниже сама подготавливает данные, выполняет запросы и очищает свою коллекцию.

Что получится

ЗаказПространство старой ссылкиРезультат
ORDER-1legacy.customerscustomer_id → Анна
ORDER-2outside.secretsотклонён без запроса к чужой коллекции

Как это работает

DBPointer хранит имя пространства и ObjectId. Он не выполняет автоматическое соединение таблиц и не создаёт внешний ключ. Получить объект ссылки — не значит загрузить клиента.

jsonSerialize даёт отдельные поля $ref и $id.$oid. Имя коллекции из данных нельзя непосредственно передавать в executeQuery. В примере разрешён только ключ legacy.customers; его значение берётся из нашей карты маршрутов. Незнакомый маршрут отклоняется до запроса.

После успешной проверки маршрута ObjectId создаётся из точной строки. Запрос выбирает только нужный _id, kind=customer и name с limit=1. Найденное имя Анна используется в отчёте; для связи сохраняется сам ObjectId.

Обновление заказа требует его текущую revision и kind. $set добавляет customer_id, $unset удаляет legacy_ref, $inc повышает revision. MatchedCount=0 означает конкурентное изменение и вызывает отказ вместо молчаливого перезаписывания.

Таблица показывает оба решения. Исходный Extended JSON остаётся в архиве программы. В реальном проекте сохраните отдельную неизменяемую копию исходного экспорта. Для новой модели применяйте обычное поле идентификатора; DBRef — другой исторический формат и не является этим DBPointer.

Границы и ошибки

Проверка существования клиента и обновление заказа здесь не общая транзакция: другой процесс мог бы изменить клиента между ними. Учебная коллекция неизменяема извне. Revision защищает только заказ и только при соблюдении протокола всеми писателями. DBPointer::__toString в драйвере 2.5.5 возвращает [namespace/ObjectId]; это диагностический текст, не формат для разбора ссылок.

Атомарное обновление и условие версии · Когда нужна общая транзакция.

Полная самостоятельная программа и архив
Заменить старую DBPointer-ссылку проверенным ObjectIdСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/sv128-helper.php';
$settings=sv128Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=sv128Command($manager,$database,['buildInfo'=>1])[0]['version'];
if(version_compare($version,'8.0','<')){throw new RuntimeException('MongoDB 8.0+ required');}
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$version,'execution'=>'database'];
$namespace=sv128Create($manager,$database,$owned);$collection=$owned[0];
$idText='507f1f77bcf86cd799439011';$customerId=new MongoDB\BSON\ObjectId($idText);
$fixture=MongoDB\BSON\Document::fromJSON('{"allowed":{"$dbPointer":{"$ref":"legacy.customers","$id":{"$oid":"507f1f77bcf86cd799439011"}}},"unexpected":{"$dbPointer":{"$ref":"outside.secrets","$id":{"$oid":"507f1f77bcf86cd799439011"}}}}');
sv128Insert($manager,$namespace,[['_id'=>$customerId,'kind'=>'customer','name'=>'Анна'],['_id'=>1,'kind'=>'order','revision'=>1,'legacy_ref'=>$fixture->get('allowed')],['_id'=>2,'kind'=>'order','revision'=>1,'legacy_ref'=>$fixture->get('unexpected')]]);
$orders=sv128Read($manager,$namespace,['kind'=>'order'],['_id'=>1,'revision'=>1,'legacy_ref'=>1],2);$routes=['legacy.customers'=>$namespace];$rows=[];$changed=0;$rejected=0;
foreach($orders as $order){
    $pointer=$order['legacy_ref'];if(!$pointer instanceof MongoDB\BSON\DBPointer){throw new RuntimeException('Expected DBPointer');}
    $value=$pointer->jsonSerialize()['$dbPointer'];$route=$value['$ref'];$id=$value['$id']['$oid'];
    if(!isset($routes[$route])){$rejected++;$rows[]=['ORDER-'.$order['_id'],$route,'отклонён без запроса к чужой коллекции'];continue;}
    $target=new MongoDB\BSON\ObjectId($id);$customer=sv128Read($manager,$routes[$route],['_id'=>$target,'kind'=>'customer'],['_id'=>1,'name'=>1],1);
    if(count($customer)!==1){throw new RuntimeException('Referenced customer does not exist');}
    $bulk=new MongoDB\Driver\BulkWrite;
    $bulk->update(['_id'=>$order['_id'],'kind'=>'order','revision'=>$order['revision']],['$set'=>['customer_id'=>$target],'$unset'=>['legacy_ref'=>''],'$inc'=>['revision'=>1]],['multi'=>false,'upsert'=>false]);
    $write=$manager->executeBulkWrite($namespace,$bulk,['writeConcern'=>new MongoDB\Driver\WriteConcern(1,3000)]);
    if($write->getMatchedCount()!==1){throw new RuntimeException('Order changed concurrently');}$changed+=$write->getModifiedCount();
    $rows[]=['ORDER-'.$order['_id'],$route,'customer_id → '.$customer[0]['name']];
}
$good=sv128Read($manager,$namespace,['_id'=>1],['_id'=>1,'customer_id'=>1,'legacy_ref'=>1,'revision'=>1],1)[0];
$bad=sv128Read($manager,$namespace,['_id'=>2],['_id'=>1,'legacy_ref'=>1,'revision'=>1],1)[0];
$checks=['one_allowed_one_rejected'=>$changed===1&&$rejected===1,'typed_manual_reference'=>$good['customer_id'] instanceof MongoDB\BSON\ObjectId&&(string)$good['customer_id']===$idText,'old_pointer_removed'=>!array_key_exists('legacy_ref',$good),'revision_advanced'=>$good['revision']===2,'unexpected_route_unchanged'=>$bad['legacy_ref'] instanceof MongoDB\BSON\DBPointer&&$bad['revision']===1,'diagnostic_string_not_parsed'=>(string)$orders[0]['legacy_ref']==='[legacy.customers/507f1f77bcf86cd799439011]'];
}finally{
    foreach(array_reverse($owned) as $name){sv128Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(sv128Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
sv128Report('mongodb128-special-dbpointer-migrate', ['Заказ', 'Пространство старой ссылки', 'Результат'], $rows, $checks, $runtime);
echo 'mongodb128-special-dbpointer-migrate: saved result.html and result.json
';
Ожидаемый результат
mongodb128-special-dbpointer-migrate: saved result.html and result.json

Реальные чтение и запись в собственной учебной коллекции; результат — HTML/JSON таблицы. Helper и README входят в архив. Только ожидаемые ошибки API перехватываются как часть урока.

Открыть фактическую таблицу · JSON тех же результатов

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

Выбрать действие по смыслу данных

ЗадачаПодходПроверка результата
Прочитать границы диагностического диапазонаMinKey/MaxKey и серверный типГраницы отличены от обычных чисел
Найти допустимые числаКонкретный тип/условие, projection, sort, limitВ выборке только нужные записи
Передать границы между PHP-слоямиМаркерные интерфейсы и штатные классыОшибочный аргумент не попал в тело функции
Разобрать старый экспортBSON-декодирование и тип каждого поляSymbol/Undefined не перепутаны со строками
Избавиться от undefinedЯвная политика unset или set nullСоседи сохранены, повторная операция не меняет исправленное
Заменить SymbolПроверка текста, точный ID и контроль измененияBSON string вместо symbol
Перенести DBPointerРазрешённая карта маршрутов, ObjectId, проверка связиЗапрещённый маршрут не вызвал внешнего запроса

Для большого массива данных сначала ограничивайте работу на сервере по конкретным ID/условию и нужным полям. Проверяйте партии и сохраняйте прогресс миграции. Учебная таблица из нескольких записей показывает смысл действия; она не обосновывает полный scan рабочей коллекции или выгрузку всего в PHP.

Справочник семи классов/интерфейсов и их методов

Карточки содержат назначение, полный текущий контракт, историю версий, ошибки и практические маршруты. DBPointer, Symbol и Undefined отмечены как устаревшие BSON-типы; их методы нужны для чтения и перехода к современной схеме.

APIДля какой задачи
MongoDB\BSON\MinKeyРазобраться, что означает нижняя граница BSON, и сохранить её тип при чтении и передаче.
MongoDB\BSON\MinKey::__constructСоздать нижняя служебную границу для BSON-документа.
MongoDB\BSON\MinKey::jsonSerializeСохранить MinKey в типизированном текстовом обмене.
MongoDB\BSON\MinKeyInterfaceУказать нижняя границу в параметре, результате функции и свойстве без выдуманных методов.
MongoDB\BSON\MaxKeyРазобраться, что означает верхняя граница BSON, и сохранить её тип при чтении и передаче.
MongoDB\BSON\MaxKey::__constructСоздать верхняя служебную границу для BSON-документа.
MongoDB\BSON\MaxKey::jsonSerializeСохранить MaxKey в типизированном текстовом обмене.
MongoDB\BSON\MaxKeyInterfaceУказать верхняя границу в параметре, результате функции и свойстве без выдуманных методов.
MongoDB\BSON\DBPointerПрочитать старую ссылку с пространством имён и ObjectId и выбрать современное представление.
MongoDB\BSON\DBPointer::__constructПонять, почему new недоступен и откуда берётся объект DBPointer.
MongoDB\BSON\DBPointer::jsonSerializeПолучить типизированную структуру DBPointer для разбора или экспорта.
MongoDB\BSON\DBPointer::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.
MongoDB\BSON\SymbolПрочитать старый символ, содержащий строковый текст и выбрать современное представление.
MongoDB\BSON\Symbol::__constructПонять, почему new недоступен и откуда берётся объект Symbol.
MongoDB\BSON\Symbol::jsonSerializeПолучить типизированную структуру Symbol для разбора или экспорта.
MongoDB\BSON\Symbol::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.
MongoDB\BSON\UndefinedПрочитать старое BSON-значение undefined и выбрать современное представление.
MongoDB\BSON\Undefined::__constructПонять, почему new недоступен и откуда берётся объект Undefined.
MongoDB\BSON\Undefined::jsonSerializeПолучить типизированную структуру Undefined для разбора или экспорта.
MongoDB\BSON\Undefined::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.

Сначала смысл поля, затем изменение типа

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

Следующие шаги: типизированный импорт и экспорт; условные изменения; чтение больших выборок ограниченными порциями.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

MongoDB\BSON\MinKeyРазобраться, что означает нижняя граница BSON, и сохранить её тип при чтении и передаче.

mongodb 1.0.0 · mongodb

final class MongoDB\BSON\MinKey implements MongoDB\BSON\MinKeyInterface, MongoDB\BSON\Type, JsonSerializable
{
    final public function __construct();
    final public function jsonSerialize(): mixed;
}

Разобраться, что означает нижняя граница BSON, и сохранить её тип при чтении и передаче.

Сигнатура и параметры

final class MongoDB\BSON\MinKey implements MongoDB\BSON\MinKeyInterface, MongoDB\BSON\Type, JsonSerializable
{
    final public function __construct();
    final public function jsonSerialize(): mixed;
}
Часть контрактаЗначение и ограничение
ЗначениеMinKey — отдельный BSON-тип без числового параметра
Созданиеnew MongoDB\BSON\MinKey()
Контрактfinal: наследовать класс нельзя; собственных публичных свойств и констант в официальном API нет

Результат и путь значения

Объект служебной границы, который драйвер записывает соответствующим BSON-типом. В порядке BSON находится раньше остальных значений. Сериализатор возвращает PHP-структуру для Extended JSON; это не поиск минимального/максимального элемента.

Ошибки

У самого класса нет отдельной операции ошибки. Конструктор и сериализация описаны в карточках ниже; операции базы и JSON имеют собственные исключения. Наличие объекта не подтверждает существование индекса или корректность пользовательского диапазона.

Версии и совместимость

Класс с mongodb 1.0.0. JsonSerializable и исторический Serializable добавлены в 1.2.0; MinKeyInterface — с 1.3.0. С mongodb 2.0.0 интерфейс Serializable удалён. Текущая глава использует API 2.5.5.

Два практических применения

Прочитать служебную границу в отчёте

Серверная таблица показывает MinKey раньше обычных значений; отдельная проверка типа отличает границу от числа.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Передать границу между слоями приложения

Типизированные параметр, возврат и свойство сохраняют объект. Экспорт и восстановление не заменяют его похожей строкой.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не используйте как отсутствующую цену, бесконечность PHP или результат SQL MIN/MAX. Обычные фильтры сравнения и сортировка имеют разные правила типов. Универсальные границы не заменяют проверку конкретного поля.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MinKey::__construct · MongoDB\BSON\MinKey::jsonSerialize.

MongoDB\BSON\MinKey::__constructСоздать нижняя служебную границу для BSON-документа.

mongodb 1.0.0 · mongodb

final public function MongoDB\BSON\MinKey::__construct()

Создать нижняя служебную границу для BSON-документа.

Сигнатура и параметры

final public function MongoDB\BSON\MinKey::__construct()

Параметров нет.

Результат и путь значения

Конструктор не возвращает отдельное значение; выражение new возвращает объект MinKey. Все объекты этого класса обозначают один вид границы, а не индивидуальное числовое значение. Запрос в MongoDB при new не выполняется.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

Конструктор существует с mongodb 1.0.0. Используется пустой список аргументов. Текущий вызов совместим с веткой 2.x.

Два практических применения

Создать воспроизводимый образец границы

new MinKey() записывается вместе с null, числом и строкой; после sort положение видно в HTML.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Проверить ошибочное предположение о диапазоне

Две новые границы входят в фильтр. Он выбирает также строки и отсутствие v — поэтому для числа нужен явный контракт.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не передавайте число в скобках. Не сравнивайте PHP-объекты произвольными операторами, рассчитывая повторить серверный порядок BSON. Для диагностики смотрите серверный $type и результат ограниченного запроса.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MinKey · MongoDB\BSON\MinKey::jsonSerialize.

MongoDB\BSON\MinKey::jsonSerializeСохранить MinKey в типизированном текстовом обмене.

mongodb 1.2.0 · mongodb

final public function MongoDB\BSON\MinKey::jsonSerialize(): mixed

Сохранить MinKey в типизированном текстовом обмене.

Сигнатура и параметры

final public function MongoDB\BSON\MinKey::jsonSerialize(): mixed

Параметров нет.

Результат и путь значения

Возвращает значение PHP для JSON-кодирования: в этой версии массив с $minKey => 1. json_encode($value) автоматически вызывает JsonSerializable; прямой jsonSerialize() ещё не выдаёт текст. Document::fromJSON восстанавливает тип из Extended JSON.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

С mongodb 1.2.0. Документация BSON-сериализаторов ссылается на Extended JSON и исторический формат: не обобщайте форму этого маркера на все BSON-типы. Удаление Serializable в 2.0.0 не отменяет JsonSerializable.

Два практических применения

Экспортировать границу без потери типа

Прямой результат сериализатора проверяется, затем типизированный документ проходит Canonical JSON и восстанавливается как MinKey.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Найти причину неверного входа в PHP-функцию

Обычный json_decode даёт array, который не удовлетворяет интерфейсу границы; таблица показывает отличие представления для транспорта и объекта для вызова.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

json_decode возвращает массив/обычный объект с маркером, а не MinKey. Не удаляйте $minKey ради красивой подписи, если другой сервис должен восстановить BSON-тип.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MinKey · MongoDB\BSON\MinKey::__construct.

MongoDB\BSON\MinKeyInterfaceУказать нижняя границу в параметре, результате функции и свойстве без выдуманных методов.

mongodb 1.3.0 · mongodb

interface MongoDB\BSON\MinKeyInterface {}

Указать нижняя границу в параметре, результате функции и свойстве без выдуманных методов.

Сигнатура и параметры

interface MongoDB\BSON\MinKeyInterface {}

Маркерный интерфейс не объявляет методов; применяется в объявлении типов.

Результат и путь значения

Интерфейс не объявляет методов. Он служит маркером допустимого PHP-типа. Штатный MinKey реализует его; функция с таким параметром получает объект, а объявленный тип результата контролирует return.

Ошибки

Создать интерфейс через new нельзя. Передача строки или другой границы в типизированный параметр вызывает TypeError; пример показывает отказ до тела функции. Интерфейс не добавляет обработку ошибок MongoDB.

Версии и совместимость

С mongodb 1.3.0. Методов jsonSerialize или __toString сам интерфейс не обещает. Эти возможности принадлежат конкретным классам/другим интерфейсам.

Два практических применения

Проверить вход и возврат функции

sv128Lower/sv128Upper принимает конкретную границу и возвращает её в выражение вызова; неверная строка отклоняется.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Сохранить роли границ в объекте настроек

Bounds128 имеет отдельные lower/upper свойства. Переставленные MinKey и MaxKey не проходят типы, что предотвращает неверную сборку документа диапазона.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Маркер описывает PHP-контракт. Из implements MinKeyInterface у самодельного класса не следует поддержка специального BSON-кодирования драйвером. Для хранения используйте штатный класс.

Document и типизированный JSON · Запись и ограниченный запрос · Интерфейс PHP.

MongoDB\BSON\MaxKeyРазобраться, что означает верхняя граница BSON, и сохранить её тип при чтении и передаче.

mongodb 1.0.0 · mongodb

final class MongoDB\BSON\MaxKey implements MongoDB\BSON\MaxKeyInterface, MongoDB\BSON\Type, JsonSerializable
{
    final public function __construct();
    final public function jsonSerialize(): mixed;
}

Разобраться, что означает верхняя граница BSON, и сохранить её тип при чтении и передаче.

Сигнатура и параметры

final class MongoDB\BSON\MaxKey implements MongoDB\BSON\MaxKeyInterface, MongoDB\BSON\Type, JsonSerializable
{
    final public function __construct();
    final public function jsonSerialize(): mixed;
}
Часть контрактаЗначение и ограничение
ЗначениеMaxKey — отдельный BSON-тип без числового параметра
Созданиеnew MongoDB\BSON\MaxKey()
Контрактfinal: наследовать класс нельзя; собственных публичных свойств и констант в официальном API нет

Результат и путь значения

Объект служебной границы, который драйвер записывает соответствующим BSON-типом. В порядке BSON находится позже остальных значений. Сериализатор возвращает PHP-структуру для Extended JSON; это не поиск минимального/максимального элемента.

Ошибки

У самого класса нет отдельной операции ошибки. Конструктор и сериализация описаны в карточках ниже; операции базы и JSON имеют собственные исключения. Наличие объекта не подтверждает существование индекса или корректность пользовательского диапазона.

Версии и совместимость

Класс с mongodb 1.0.0. JsonSerializable и исторический Serializable добавлены в 1.2.0; MaxKeyInterface — с 1.3.0. С mongodb 2.0.0 интерфейс Serializable удалён. Текущая глава использует API 2.5.5.

Два практических применения

Прочитать служебную границу в отчёте

Серверная таблица показывает MaxKey позже обычных значений; отдельная проверка типа отличает границу от числа.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Передать границу между слоями приложения

Типизированные параметр, возврат и свойство сохраняют объект. Экспорт и восстановление не заменяют его похожей строкой.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не используйте как отсутствующую цену, бесконечность PHP или результат SQL MIN/MAX. Обычные фильтры сравнения и сортировка имеют разные правила типов. Универсальные границы не заменяют проверку конкретного поля.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MaxKey::__construct · MongoDB\BSON\MaxKey::jsonSerialize.

MongoDB\BSON\MaxKey::__constructСоздать верхняя служебную границу для BSON-документа.

mongodb 1.0.0 · mongodb

final public function MongoDB\BSON\MaxKey::__construct()

Создать верхняя служебную границу для BSON-документа.

Сигнатура и параметры

final public function MongoDB\BSON\MaxKey::__construct()

Параметров нет.

Результат и путь значения

Конструктор не возвращает отдельное значение; выражение new возвращает объект MaxKey. Все объекты этого класса обозначают один вид границы, а не индивидуальное числовое значение. Запрос в MongoDB при new не выполняется.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

Конструктор существует с mongodb 1.0.0. Используется пустой список аргументов. Текущий вызов совместим с веткой 2.x.

Два практических применения

Создать воспроизводимый образец границы

new MaxKey() записывается вместе с null, числом и строкой; после sort положение видно в HTML.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Проверить ошибочное предположение о диапазоне

Две новые границы входят в фильтр. Он выбирает также строки и отсутствие v — поэтому для числа нужен явный контракт.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не передавайте число в скобках. Не сравнивайте PHP-объекты произвольными операторами, рассчитывая повторить серверный порядок BSON. Для диагностики смотрите серверный $type и результат ограниченного запроса.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MaxKey · MongoDB\BSON\MaxKey::jsonSerialize.

MongoDB\BSON\MaxKey::jsonSerializeСохранить MaxKey в типизированном текстовом обмене.

mongodb 1.2.0 · mongodb

final public function MongoDB\BSON\MaxKey::jsonSerialize(): mixed

Сохранить MaxKey в типизированном текстовом обмене.

Сигнатура и параметры

final public function MongoDB\BSON\MaxKey::jsonSerialize(): mixed

Параметров нет.

Результат и путь значения

Возвращает значение PHP для JSON-кодирования: в этой версии массив с $maxKey => 1. json_encode($value) автоматически вызывает JsonSerializable; прямой jsonSerialize() ещё не выдаёт текст. Document::fromJSON восстанавливает тип из Extended JSON.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

С mongodb 1.2.0. Документация BSON-сериализаторов ссылается на Extended JSON и исторический формат: не обобщайте форму этого маркера на все BSON-типы. Удаление Serializable в 2.0.0 не отменяет JsonSerializable.

Два практических применения

Экспортировать границу без потери типа

Прямой результат сериализатора проверяется, затем типизированный документ проходит Canonical JSON и восстанавливается как MaxKey.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Найти причину неверного входа в PHP-функцию

Обычный json_decode даёт array, который не удовлетворяет интерфейсу границы; таблица показывает отличие представления для транспорта и объекта для вызова.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

json_decode возвращает массив/обычный объект с маркером, а не MaxKey. Не удаляйте $maxKey ради красивой подписи, если другой сервис должен восстановить BSON-тип.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\MaxKey · MongoDB\BSON\MaxKey::__construct.

MongoDB\BSON\MaxKeyInterfaceУказать верхняя границу в параметре, результате функции и свойстве без выдуманных методов.

mongodb 1.3.0 · mongodb

interface MongoDB\BSON\MaxKeyInterface {}

Указать верхняя границу в параметре, результате функции и свойстве без выдуманных методов.

Сигнатура и параметры

interface MongoDB\BSON\MaxKeyInterface {}

Маркерный интерфейс не объявляет методов; применяется в объявлении типов.

Результат и путь значения

Интерфейс не объявляет методов. Он служит маркером допустимого PHP-типа. Штатный MaxKey реализует его; функция с таким параметром получает объект, а объявленный тип результата контролирует return.

Ошибки

Создать интерфейс через new нельзя. Передача строки или другой границы в типизированный параметр вызывает TypeError; пример показывает отказ до тела функции. Интерфейс не добавляет обработку ошибок MongoDB.

Версии и совместимость

С mongodb 1.3.0. Методов jsonSerialize или __toString сам интерфейс не обещает. Эти возможности принадлежат конкретным классам/другим интерфейсам.

Два практических применения

Проверить вход и возврат функции

sv128Lower/sv128Upper принимает конкретную границу и возвращает её в выражение вызова; неверная строка отклоняется.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Сохранить роли границ в объекте настроек

Bounds128 имеет отдельные lower/upper свойства. Переставленные MinKey и MaxKey не проходят типы, что предотвращает неверную сборку документа диапазона.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Маркер описывает PHP-контракт. Из implements MaxKeyInterface у самодельного класса не следует поддержка специального BSON-кодирования драйвером. Для хранения используйте штатный класс.

Document и типизированный JSON · Запись и ограниченный запрос · Интерфейс PHP.

MongoDB\BSON\DBPointerПрочитать старую ссылку с пространством имён и ObjectId и выбрать современное представление.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final class MongoDB\BSON\DBPointer implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}

Прочитать старую ссылку с пространством имён и ObjectId и выбрать современное представление.

Сигнатура и параметры

final class MongoDB\BSON\DBPointer implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}
Часть контрактаЗначение и ограничение
ПолучениеДекодирование BSON/Extended JSON; конструктор не публичный
РольСовместимость со старыми данными, не рекомендуемый тип новой схемы
Состояниеfinal-класс; официально объявленных публичных свойств/констант нет

Результат и путь значения

Декодер возвращает объект DBPointer, который можно проверить instanceof. Сериализация сохраняет специальный маркер; строковое представление служит отдельно для вывода. Современный путь для новых записей: обычное поле customer_id с ObjectId и разрешённым маршрутом чтения.

Ошибки

new MongoDB\BSON\DBPointer() вызывает PHP Error из-за private-конструктора. Ошибки декодирования Extended JSON, записи и чтения относятся к соответствующим API. Отсутствующий клиент/недопустимый статус требуют собственной политики приложения.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет dbPointer отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Сверить маршрут и перенести связь

ORDER-1 получает customer_id → Анна; ORDER-2 с неизвестным маршрутом остаётся без изменения и без внешнего запроса.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не создавайте новые прикладные данные устаревшего типа. Отладочный вывод свойств не является документированным API доступа. Используйте проверку класса и jsonSerialize/типизированный экспорт. Для DBPointer::__toString есть расхождение с просмотренной страницей PHP.net: там указана пустая строка, но tagged исходник и тест драйвера 2.5.5, а также реальный запуск возвращают [namespace/ObjectId]. Здесь описана проверенная версия 2.5.5. Разбирать этот текст для миграции не нужно.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\DBPointer::__construct · MongoDB\BSON\DBPointer::jsonSerialize · MongoDB\BSON\DBPointer::__toString.

MongoDB\BSON\DBPointer::__constructПонять, почему new недоступен и откуда берётся объект DBPointer.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final private function MongoDB\BSON\DBPointer::__construct()

Понять, почему new недоступен и откуда берётся объект DBPointer.

Сигнатура и параметры

final private function MongoDB\BSON\DBPointer::__construct()

Параметров нет.

Результат и путь значения

Метод не предназначен для вызова из пользовательского PHP-кода и не конструирует значение по переданным данным. Объекты появляются при декодировании соответствующего BSON-типа. Воспроизводимый учебный архив использует Document::fromJSON, а не обход видимости.

Ошибки

Вызов new MongoDB\BSON\DBPointer() из общего контекста завершается Error о private-конструкторе. Это ожидаемое ограничение API. Для Document::fromJSON некорректный JSON/непреобразуемый формат вызывает MongoDB\Driver\Exception\UnexpectedValueException; отсутствие ключа при Document::get — RuntimeException.

Версии и совместимость

С mongodb 1.4.0; private-конструктор сохранён в 2.5.5. Поддержка чтения не означает наличие публичной фабрики для новых устаревших данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет dbPointer отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Сверить маршрут и перенести связь

ORDER-1 получает customer_id → Анна; ORDER-2 с неизвестным маршрутом остаётся без изменения и без внешнего запроса.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не заменяйте ошибку private на reflection/unserialize-трюк. Для новой записи выберите обычное поле customer_id с ObjectId и разрешённым маршрутом чтения. В учебном примере старый fixture нужен исключительно для проверки миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\DBPointer · MongoDB\BSON\DBPointer::jsonSerialize · MongoDB\BSON\DBPointer::__toString.

MongoDB\BSON\DBPointer::jsonSerializeПолучить типизированную структуру DBPointer для разбора или экспорта.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\DBPointer::jsonSerialize(): mixed

Получить типизированную структуру DBPointer для разбора или экспорта.

Сигнатура и параметры

final public function MongoDB\BSON\DBPointer::jsonSerialize(): mixed

Параметров нет.

Результат и путь значения

Метод возвращает PHP-значение для json_encode; для нашего fixture структура: ["$dbPointer" => ["$ref" => "legacy.customers", "$id" => ["$oid" => "507f1f77bcf86cd799439011"]]]. Это ещё не JSON-строка. Автоматический вызов при json_encode($value) связан с JsonSerializable; Document::fromJSON понимает типизированный текст при обратном чтении.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

С mongodb 1.4.0. Официальный контракт описывает Extended JSON и исторические BSON-типы. Не считайте это общим DTO для браузера: обычный json_decode не создаёт DBPointer.

Два практических применения

Прочитать разрешённый маршрут ссылки

jsonSerialize отделяет $ref. Маршрут legacy.customers разрешается явной картой, outside.secrets отклоняется до запроса.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Восстановить идентификатор новой связи

Из $id.$oid берётся точная строка ObjectId; после проверки клиента ORDER-1 получает customer_id. Диагностическая строка не разбирается.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Сначала проверьте тип объекта. Маркерный JSON не даёт разрешения выполнять запросы или менять данные. Для обычного современного API подготовьте явный DTO после выбранной миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\DBPointer · MongoDB\BSON\DBPointer::__construct · MongoDB\BSON\DBPointer::__toString.

MongoDB\BSON\DBPointer::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\DBPointer::__toString(): string

Получить строковое представление и понять, какие сведения оно скрывает.

Сигнатура и параметры

final public function MongoDB\BSON\DBPointer::__toString(): string

Параметров нет.

Результат и путь значения

В проверенном ext-mongodb 2.5.5 возвращает диагностическую строку [legacy.customers/507f1f77bcf86cd799439011]. Поля namespace и ObjectId в ней соединены; метод не загружает связанный документ.

Ошибки

Параметров нет. Это преобразование объекта в строку, а не операция базы. Вывод в HTML всё равно требует экранирования. Не используйте строковый вид как доказательство нужного BSON-типа.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных. Для DBPointer::__toString есть расхождение с просмотренной страницей PHP.net: там указана пустая строка, но tagged исходник и тест драйвера 2.5.5, а также реальный запуск возвращают [namespace/ObjectId]. Здесь описана проверенная версия 2.5.5. Разбирать этот текст для миграции не нужно.

Два практических применения

Подписать старую ссылку в диагностике

Строка показывает пространство legacy.customers и ID; подпись экранируется для HTML.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Отделить подпись от разрешённого запроса

Строка подтверждает диагностический формат, но маршрутизация использует отдельные поля jsonSerialize и карту разрешений.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Явный __toString() и (string)$value вызывают строковое представление. Оно не сохраняет весь контракт BSON. Для экспорта с типом используйте jsonSerialize/Canonical Extended JSON; для новой схемы — обычное поле customer_id с ObjectId и разрешённым маршрутом чтения.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\DBPointer · MongoDB\BSON\DBPointer::__construct · MongoDB\BSON\DBPointer::jsonSerialize.

MongoDB\BSON\SymbolПрочитать старый символ, содержащий строковый текст и выбрать современное представление.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final class MongoDB\BSON\Symbol implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}

Прочитать старый символ, содержащий строковый текст и выбрать современное представление.

Сигнатура и параметры

final class MongoDB\BSON\Symbol implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}
Часть контрактаЗначение и ограничение
ПолучениеДекодирование BSON/Extended JSON; конструктор не публичный
РольСовместимость со старыми данными, не рекомендуемый тип новой схемы
Состояниеfinal-класс; официально объявленных публичных свойств/констант нет

Результат и путь значения

Декодер возвращает объект Symbol, который можно проверить instanceof. Сериализация сохраняет специальный маркер; строковое представление служит отдельно для вывода. Современный путь для новых записей: обычную строку после проверки допустимого значения.

Ошибки

new MongoDB\BSON\Symbol() вызывает PHP Error из-за private-конструктора. Ошибки декодирования Extended JSON, записи и чтения относятся к соответствующим API. Отсутствующий клиент/недопустимый статус требуют собственной политики приложения.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет symbol отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Привести статус к современному строковому контракту

Старый Symbol published становится строкой published; уже строковый сосед остаётся без изменения.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не создавайте новые прикладные данные устаревшего типа. Отладочный вывод свойств не является документированным API доступа. Используйте проверку класса и jsonSerialize/типизированный экспорт.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Symbol::__construct · MongoDB\BSON\Symbol::jsonSerialize · MongoDB\BSON\Symbol::__toString.

MongoDB\BSON\Symbol::__constructПонять, почему new недоступен и откуда берётся объект Symbol.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final private function MongoDB\BSON\Symbol::__construct()

Понять, почему new недоступен и откуда берётся объект Symbol.

Сигнатура и параметры

final private function MongoDB\BSON\Symbol::__construct()

Параметров нет.

Результат и путь значения

Метод не предназначен для вызова из пользовательского PHP-кода и не конструирует значение по переданным данным. Объекты появляются при декодировании соответствующего BSON-типа. Воспроизводимый учебный архив использует Document::fromJSON, а не обход видимости.

Ошибки

Вызов new MongoDB\BSON\Symbol() из общего контекста завершается Error о private-конструкторе. Это ожидаемое ограничение API. Для Document::fromJSON некорректный JSON/непреобразуемый формат вызывает MongoDB\Driver\Exception\UnexpectedValueException; отсутствие ключа при Document::get — RuntimeException.

Версии и совместимость

С mongodb 1.4.0; private-конструктор сохранён в 2.5.5. Поддержка чтения не означает наличие публичной фабрики для новых устаревших данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет symbol отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Привести статус к современному строковому контракту

Старый Symbol published становится строкой published; уже строковый сосед остаётся без изменения.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не заменяйте ошибку private на reflection/unserialize-трюк. Для новой записи выберите обычную строку после проверки допустимого значения. В учебном примере старый fixture нужен исключительно для проверки миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Symbol · MongoDB\BSON\Symbol::jsonSerialize · MongoDB\BSON\Symbol::__toString.

MongoDB\BSON\Symbol::jsonSerializeПолучить типизированную структуру Symbol для разбора или экспорта.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\Symbol::jsonSerialize(): mixed

Получить типизированную структуру Symbol для разбора или экспорта.

Сигнатура и параметры

final public function MongoDB\BSON\Symbol::jsonSerialize(): mixed

Параметров нет.

Результат и путь значения

Метод возвращает PHP-значение для json_encode; для нашего fixture структура: ["$symbol" => "published"]. Это ещё не JSON-строка. Автоматический вызов при json_encode($value) связан с JsonSerializable; Document::fromJSON понимает типизированный текст при обратном чтении.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

С mongodb 1.4.0. Официальный контракт описывает Extended JSON и исторические BSON-типы. Не считайте это общим DTO для браузера: обычный json_decode не создаёт Symbol.

Два практических применения

Сохранить исходный тип статуса для разбора экспорта

Прямой jsonSerialize проверяет $symbol: published; Canonical-путь затем восстанавливает Symbol, сохраняя отличие от обычной строки.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Отделить архивный контракт от нового API

В программе одновременно видны исходный $symbol и новая строка published. Типизированный экспорт нужен для сохранения старой семантики, а проверенное преобразование — для современного поля.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Сначала проверьте тип объекта. Маркерный JSON не даёт разрешения выполнять запросы или менять данные. Для обычного современного API подготовьте явный DTO после выбранной миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Symbol · MongoDB\BSON\Symbol::__construct · MongoDB\BSON\Symbol::__toString.

MongoDB\BSON\Symbol::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\Symbol::__toString(): string

Получить строковое представление и понять, какие сведения оно скрывает.

Сигнатура и параметры

final public function MongoDB\BSON\Symbol::__toString(): string

Параметров нет.

Результат и путь значения

Возвращает сохранённый текст published.

Ошибки

Параметров нет. Это преобразование объекта в строку, а не операция базы. Вывод в HTML всё равно требует экранирования. Не используйте строковый вид как доказательство нужного BSON-типа.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных.

Два практических применения

Увидеть неоднозначность обычного echo

Symbol выглядит как соседняя строка published; отчёт добавляет тип, чтобы не принять одно за другое.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Получить текст для проверенной новой записи

(string) даёт published; allowlist проверяет значение до записи обычной строки.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Явный __toString() и (string)$value вызывают строковое представление. Оно не сохраняет весь контракт BSON. Для экспорта с типом используйте jsonSerialize/Canonical Extended JSON; для новой схемы — обычную строку после проверки допустимого значения.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Symbol · MongoDB\BSON\Symbol::__construct · MongoDB\BSON\Symbol::jsonSerialize.

MongoDB\BSON\UndefinedПрочитать старое BSON-значение undefined и выбрать современное представление.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final class MongoDB\BSON\Undefined implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}

Прочитать старое BSON-значение undefined и выбрать современное представление.

Сигнатура и параметры

final class MongoDB\BSON\Undefined implements MongoDB\BSON\Type, JsonSerializable, Stringable
{
    final private function __construct();
    final public function jsonSerialize(): mixed;
    final public function __toString(): string;
}
Часть контрактаЗначение и ограничение
ПолучениеДекодирование BSON/Extended JSON; конструктор не публичный
РольСовместимость со старыми данными, не рекомендуемый тип новой схемы
Состояниеfinal-класс; официально объявленных публичных свойств/констант нет

Результат и путь значения

Декодер возвращает объект Undefined, который можно проверить instanceof. Сериализация сохраняет специальный маркер; строковое представление служит отдельно для вывода. Современный путь для новых записей: удаление ключа или явный null по заранее выбранному правилу.

Ошибки

new MongoDB\BSON\Undefined() вызывает PHP Error из-за private-конструктора. Ошибки декодирования Extended JSON, записи и чтения относятся к соответствующим API. Отсутствующий клиент/недопустимый статус требуют собственной политики приложения.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет undefined отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Исправить неизвестное значение по правилу приложения

ID 1 становится missing, ID 2 — null; строка undefined и соседние состояния сохраняются.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не создавайте новые прикладные данные устаревшего типа. Отладочный вывод свойств не является документированным API доступа. Используйте проверку класса и jsonSerialize/типизированный экспорт.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Undefined::__construct · MongoDB\BSON\Undefined::jsonSerialize · MongoDB\BSON\Undefined::__toString.

MongoDB\BSON\Undefined::__constructПонять, почему new недоступен и откуда берётся объект Undefined.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final private function MongoDB\BSON\Undefined::__construct()

Понять, почему new недоступен и откуда берётся объект Undefined.

Сигнатура и параметры

final private function MongoDB\BSON\Undefined::__construct()

Параметров нет.

Результат и путь значения

Метод не предназначен для вызова из пользовательского PHP-кода и не конструирует значение по переданным данным. Объекты появляются при декодировании соответствующего BSON-типа. Воспроизводимый учебный архив использует Document::fromJSON, а не обход видимости.

Ошибки

Вызов new MongoDB\BSON\Undefined() из общего контекста завершается Error о private-конструкторе. Это ожидаемое ограничение API. Для Document::fromJSON некорректный JSON/непреобразуемый формат вызывает MongoDB\Driver\Exception\UnexpectedValueException; отсутствие ключа при Document::get — RuntimeException.

Версии и совместимость

С mongodb 1.4.0; private-конструктор сохранён в 2.5.5. Поддержка чтения не означает наличие публичной фабрики для новых устаревших данных.

Два практических применения

Обнаружить тип в архиве перед изменением

Инвентаризация сохраняет undefined отдельно от string, null и missing; private-конструктор не вызывается для получения исходных данных.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Исправить неизвестное значение по правилу приложения

ID 1 становится missing, ID 2 — null; строка undefined и соседние состояния сохраняются.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Не заменяйте ошибку private на reflection/unserialize-трюк. Для новой записи выберите удаление ключа или явный null по заранее выбранному правилу. В учебном примере старый fixture нужен исключительно для проверки миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Undefined · MongoDB\BSON\Undefined::jsonSerialize · MongoDB\BSON\Undefined::__toString.

MongoDB\BSON\Undefined::jsonSerializeПолучить типизированную структуру Undefined для разбора или экспорта.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\Undefined::jsonSerialize(): mixed

Получить типизированную структуру Undefined для разбора или экспорта.

Сигнатура и параметры

final public function MongoDB\BSON\Undefined::jsonSerialize(): mixed

Параметров нет.

Результат и путь значения

Метод возвращает PHP-значение для json_encode; для нашего fixture структура: ["$undefined" => true]. Это ещё не JSON-строка. Автоматический вызов при json_encode($value) связан с JsonSerializable; Document::fromJSON понимает типизированный текст при обратном чтении.

Ошибки

Параметров нет. Страница метода документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Не передавайте фиктивное значение или настройку: у этой операции нет такого контракта. Ошибки последующего JSON-кодирования, декодирования или запроса обрабатываются отдельно.

Версии и совместимость

С mongodb 1.4.0. Официальный контракт описывает Extended JSON и исторические BSON-типы. Не считайте это общим DTO для браузера: обычный json_decode не создаёт Undefined.

Два практических применения

Выдать явный диагностический маркер вместо пустого текста

jsonSerialize возвращает $undefined: true; json_encode вызывает этот метод автоматически и полученный маркер проверяется в программе.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Проверить, что транспорт не скрыл особое состояние

После JSON-кодирования и обычного json_decode остаётся структура с $undefined. Рядом реальная выборка отличает исходный объект от null, missing и пустой строки; обычный decoder не становится BSON-фабрикой.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Сначала проверьте тип объекта. Маркерный JSON не даёт разрешения выполнять запросы или менять данные. Для обычного современного API подготовьте явный DTO после выбранной миграции.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Undefined · MongoDB\BSON\Undefined::__construct · MongoDB\BSON\Undefined::__toString.

MongoDB\BSON\Undefined::__toStringПолучить строковое представление и понять, какие сведения оно скрывает.

mongodb 1.4.0; устаревший BSON-тип · mongodb

final public function MongoDB\BSON\Undefined::__toString(): string

Получить строковое представление и понять, какие сведения оно скрывает.

Сигнатура и параметры

final public function MongoDB\BSON\Undefined::__toString(): string

Параметров нет.

Результат и путь значения

Возвращает пустую строку "". Это строковое представление, а не замена BSON-значения на null или отсутствие поля.

Ошибки

Параметров нет. Это преобразование объекта в строку, а не операция базы. Вывод в HTML всё равно требует экранирования. Не используйте строковый вид как доказательство нужного BSON-типа.

Версии и совместимость

Класс и методы с mongodb 1.4.0. С 1.12.0 на PHP 8 реализуется Stringable. С mongodb 2.0.0 удалён исторический Serializable; JsonSerializable сохранён. BSON-тип устарел: поддержка декодирования нужна для существующих данных.

Два практических применения

Объяснить пустую ячейку старого отчёта

Undefined приводит к пустому тексту, поэтому диагностическая таблица выводит имя типа и отдельные ID.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Не спутать отображение с политикой хранения

Вместо превращения всего пустого вывода в null проверяется настоящий тип, затем применяется unset или set по правилу.

Исходные данные, короткий вызов, программа и разбор результата · Таблица реального запуска

Границы и связанные инструменты

Явный __toString() и (string)$value вызывают строковое представление. Оно не сохраняет весь контракт BSON. Для экспорта с типом используйте jsonSerialize/Canonical Extended JSON; для новой схемы — удаление ключа или явный null по заранее выбранному правилу.

Document и типизированный JSON · Запись и ограниченный запрос · MongoDB\BSON\Undefined · MongoDB\BSON\Undefined::__construct · MongoDB\BSON\Undefined::jsonSerialize.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.