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

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

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

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

Глава 164 · После PHP-массивов, объектов и основ Query

MongoDB: бинарные файлы, UUID и компактные векторы

От bytes и точного UUID-фильтра до Float32, signed Int8, PackedBit, проверки размерности и экспорта только выбранных профилей.

От бинарного поля к понятному результату

У сервиса появились данные, которые не стоит считать обычным текстом: двоичный пакет датчика, UUID заказа и числовые признаки товара. В этой главе сохраним их в MongoDB, прочитаем обратно и построим понятные результаты: таблицу байтов, найденный заказ, поправки датчиков, комплектацию и небольшой экспорт выбранных признаков.

Байт — восемь битов, одна позиция со значением 0..255. PHP string способен хранить такие bytes, включая нулевой байт, но HTML и JSON ожидают текст по своим правилам. Binary добавляет к байтам BSON-подтип — подпись того, как их понимать. Эта подпись важна при сохранении и поиске.

Один фрагмент, разные способы его увидеть
  1. Исходные bytes: A, NUL, FF → три байта 41 00 FF
  2. Binary: те же bytes + subtype 0 → поле MongoDB
  3. getData(): исходные bytes; bin2hex(): 4100ff; base64: QQD/
  4. Интерфейс показывает подпись и безопасное представление, а не сырой поток

Представьте конверт с образцом и подписью формата. Содержимое — bytes, подпись — subtype. Подпись помогает выбрать способ чтения, но не доказывает правильность содержимого. Аналогия не описывает физическое хранение MongoDB и не означает шифрования.

$binary = new MongoDB\BSON\Binary("A\0\xFF", MongoDB\BSON\Binary::TYPE_GENERIC);
echo strlen($binary->getData()); // 3 байта
echo bin2hex($binary->getData()); // 4100ff

Первая строка присваивает $binary созданный объект. new вызывает конструктор; запятая разделяет bytes и подтип. :: читает константу класса, -> вызывает метод объекта, скобки () показывают вызов без аргументов. Нулевой байт и FF входят в данные, но для их отображения выбран hex. Сам конструктор ещё не сделал запись в базу — это появится в первой полной программе.

Предварительные объяснения: строки и байты, списки и ключи массива, Manager, документы, Query и projection. Для других точных BSON-типов есть ObjectId, время и Decimal128; для текстовых условий — Regex и запросы.

Байты, подтип, UUID, вектор и текстовое представление

ПредставлениеЧто в нёмКогда пригодится
PHP string bytesПроизвольная последовательность; UTF-8 не гарантированаЧтение файла, вычисление хеша, двоичный протокол
Binary subtype 0Bytes + метка genericНебольшое двоичное вложение документа
Binary subtype 4Ровно 16 байтов UUIDПоиск по UUID того же BSON-типа
Binary subtype 9Metadata + компактные однотипные компонентыФиксированные числовые или битовые признаки
Hex / base64Текстовое представление bytesДиагностика или согласованный обмен
Canonical Extended JSONТекст с явным BSON-подтипомПеренос типизированного документа

Номер Binary subtype не равен номеру BSON-типа поля. MongoDB относит любое Binary к BSON binData; внутри него уже выбирается subtype 0, 4, 9 и т. д. Поэтому getType() Binary читает именно внутреннюю метку. Нельзя передать номер 9 в общий BSON $type-фильтр и ожидать «vector»: у BSON-типов собственная нумерация.

Вектор — список компонент фиксированного смысла и порядка. Float32, Int8 и PackedBit — способы хранить компоненты. Они не вычисляют признаки, не обучают модель и не запускают поиск ближайших соседей. Здесь используются понятные вручную заданные значения, а не выдуманные эмбеддинги.

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

Все девять архивов самостоятельны. Нужны PHP CLI 8.4+ x64, ext-mongodb 2.5+ и отдельный локальный MongoDB 8.0+. Проверяемая среда пакета: PHP 8.5.11 / mongodb 2.5.5 / MongoDB 8.0.34. Векторные методы существуют с 2.2.0, но полный учебный комплект рассчитан на указанную среду. Composer не требуется.

$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 из распакованного каталога. README.txt каждого архива объясняет установку расширения, проверку CLI php.ini, отдельный dbpath и запуск mongod на loopback. Не подставляйте производственный URI. Helper требует явное учебное ASCII-имя базы и не принимает admin/local/config или учётные данные в URI.

Каждая программа создаёт ровно одну собственную коллекцию mongodb126_binary_ со случайной частью, записывает небольшой набор данных и выбирает нужные поля с пределом до десяти документов. В finally удаляется только созданное точное имя, после чего проверяется отсутствие коллекции. Первый пример также создаёт собственный файл через x+b и удаляет его. Прочие файлы и базы не меняются.

Сохранить байты файла и проверить их после чтения

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

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

Программа сама создаёт отдельный sensor-frame.bin: A, NUL, FF, B, CR и LF. Это учебный бинарный фрагмент, а не повреждённая строка и не замена настоящего изображения. В MongoDB сохраняются имя пакета и поле payload.

Как данные превращаются в результат
  1. Файл: 41 00 FF 42 0D 0A — шесть исходных байтов
  2. Binary: payload: subtype 0 + те же bytes
  3. MongoDB: запись 101, отдельная собственная коллекция
  4. Чтение: 6 байтов; hex 4100ff420d0a; SHA256 совпадает

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

$binary = new MongoDB\BSON\Binary("A\0\xFF", MongoDB\BSON\Binary::TYPE_GENERIC);
echo bin2hex($binary->getData()); // 4100ff

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

Результат выполнения

ЗаписьПодтипБайтHex прочитанных байтовSHA256 совпадаетBase64 для диагностики
Пакет датчика064100ff420d0atrueQQD/Qg0K

Как это устроено

new создаёт объект Binary. Первый аргумент — содержимое, второй — метка его формата. TYPE_GENERIC равен 0 и подходит произвольным байтам. Ни кодирование base64, ни сжатие здесь не происходят. Кавычки PHP с \0 и \xFF позволяют задать байты: после выполнения это уже не текст из четырёх символов «\xFF».

getData() возвращает исходную PHP-строку байтов. strlen() считает байты, bin2hex() даёт безопасное для чтения шестнадцатеричное представление: одному байту соответствуют две цифры. Приведение (string) вызывает __toString() и возвращает те же исходные байты.

x+b создаёт новый файл и отказывает при совпадении имени. Код сохраняет признак собственного создания, закрывает ресурс, удаляет только свой файл. Для коллекции применяется такой же принцип владения. Запись идёт до Query, поэтому таблица строится по реальному прочитанному полю payload.

SHA256 сравнивается до и после хранения. Дополнительное legacy Extended JSON представление годится для совместимого диагностического обмена: QQD/Qg0K — base64 этих шести байтов, а 00 — подтип. Такой журнал всё равно может содержать чувствительное содержимое: base64 легко декодируется.

Границы и типичные ошибки

Binary хранится внутри BSON-документа, чей предел обычно 16 MiB вместе со всеми полями. Для больших файлов рассматривают файловое хранилище или GridFS, а не огромный массив документов в PHP. Совпадение SHA256 здесь доказывает целостность учебного фрагмента при переносе; оно не удостоверяет источник. В интерфейс выводятся hex и безопасные подписи, исходные байты в HTML не вставляются.

Полная самостоятельная программа и архив
Сохранить байты файла и проверить их после чтенияСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$path=__DIR__.'/sensor-frame.bin';$ownedFile=false;$handle=null;
try{
    $handle=fopen($path,'x+b');if($handle===false){throw new RuntimeException('Cannot create an owned fixture file');}$ownedFile=true;
    $original="A\0\xFFB\r\n";
    if(fwrite($handle,$original)!==strlen($original)){throw new RuntimeException('Short file write');}
    rewind($handle);$bytes=stream_get_contents($handle);
    if($bytes===false){throw new RuntimeException('Cannot read owned file');}
    fclose($handle);$handle=null;
    $binary=new MongoDB\BSON\Binary($bytes,MongoDB\BSON\Binary::TYPE_GENERIC);
    bv126Insert($manager,$namespace,[['_id'=>101,'name'=>'Пакет датчика','payload'=>$binary]]);
    $doc=bv126Read($manager,$namespace,['_id'=>101],['_id'=>1,'name'=>1,'payload'=>1],1)[0];
    $read=$doc['payload'];$summary=bv126Summary($read);$sameHash=hash('sha256',$original)===hash('sha256',$read->getData());
    $safeDiagnostic=$read->jsonSerialize();
    $rows=[[$doc['name'],$summary['subtype'],$summary['bytes'],$summary['hex'],$sameHash,$safeDiagnostic['$binary']]];
    $checks=['raw_bytes_roundtrip'=>$read->getData()===$original,'string_alias_same'=>(string)$read===$original,
        'generic_type'=>$read->getType()===MongoDB\BSON\Binary::TYPE_GENERIC,'contains_nul_and_non_utf8'=>bin2hex($bytes)==='4100ff420d0a','sha256_matches'=>$sameHash,
        'diagnostic_binary_keeps_subtype'=>$safeDiagnostic===['$binary'=>'QQD/Qg0K','$type'=>'00']];
}finally{
    if(is_resource($handle)){fclose($handle);}
    if($ownedFile && !unlink($path)){throw new RuntimeException('Cannot remove own fixture file');}
}
$checks['own_file_removed']=$ownedFile && !file_exists($path);
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-binary-file', ['Запись', 'Подтип', 'Байт', 'Hex прочитанных байтов', 'SHA256 совпадает', 'Base64 для диагностики'], $rows, $checks, $runtime);
echo 'mongodb126-binary-binary-file: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-binary-file: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Замените B на C. Предполагаемый hex изменится с 4100ff420d0a на 4100ff430d0a, длина останется 6. Сравнение SHA256 между новым входом и его прочитанной копией по-прежнему должно дать true.

Найти заказ по UUID из текстового поля формы

Форма поиска заказа прислала UUID с дефисами. Заказ есть в MongoDB, но поиск этой строкой ничего не находит: в базе лежит бинарный UUID. Покажем переход от текста формы к значению того же BSON-типа.

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

Известный UUID 00112233-4455-4677-8899-aabbccddeeff принадлежит учебному заказу 201 на 4500 копеек. В примере есть верный ввод в верхнем регистре, заведомо неверный текст и попытка создать UUID из пяти байтов.

Как данные превращаются в результат
  1. Форма: 00112233-4455-4677-8899-aabbccddeeff
  2. Проверка: 32 hex-цифры + дефисы на нужных местах
  3. Преобразование: hex2bin → 16 bytes → Binary subtype 4
  4. Query: order_uuid имеет тот же тип → заказ 201

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

$bytes = hex2bin('00112233445546778899aabbccddeeff'); // известный корректный UUID
$uuid = new MongoDB\BSON\Binary($bytes, MongoDB\BSON\Binary::TYPE_UUID);
$filter = ['order_uuid' => $uuid]; // Binary, а не строка с дефисами

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

Результат выполнения

Фильтр / проверкаРезультатСмысл
Строка UUID0совпадения нет
Binary subtype 41заказ 201, 4500 коп.
Неверный текст отклонёнtrueдо запроса
UUID из 5 байт отклонёнtrueконструктором Binary

Как это устроено

UUID — 128-битный идентификатор, обычно отображаемый как 32 hex-цифры с четырьмя дефисами. Текст удобен человеку, а Binary subtype 4 представляет эти 16 байтов в BSON. Строка и Binary различаются даже тогда, когда человек видит в них «один UUID».

uuid126() сначала проверяет форму строки. Регулярное выражение здесь не учит генерировать UUID: оно лишь допускает шестнадцатеричные группы нужной длины. Затем str_replace убирает дефисы, strtolower унифицирует регистр, hex2bin превращает каждую пару цифр в один байт.

TYPE_UUID выбирает текущий стандартный подтип 4. Передавать конструктору сами 36 символов с дефисами нельзя: он ждёт 16 байтов. Конструктор обнаруживает неверную длину и бросает MongoDB\Driver\Exception\InvalidArgumentException; неверный формат формы отклоняет собственная функция ещё до Query.

В полном примере один Query получает ноль строк, другой — именно заказ 201. Это не потеря документа и не ошибка сортировки: отличается тип фильтра. Ограниченный projection возвращает только необходимые поля, limit равен 1.

Границы и типичные ошибки

Проверка формата не доказывает, что UUID выдан вашим сервисом, и не заменяет проверку доступа к заказу. Для действительного пользовательского запроса добавляют tenant/owner в фильтр. Пример не проверяет все семантические версии UUID и не является его генератором. Уже существующий ObjectId — другой BSON-тип; произвольная подмена его UUID недопустима.

Полная самостоятельная программа и архив
Найти заказ по UUID из текстового поля формыСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
function uuid126(string $text): MongoDB\BSON\Binary {
    if(!preg_match('/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/iD',$text)){
        throw new InvalidArgumentException('Expected canonical UUID text');
    }
    $bytes=hex2bin(str_replace('-','',strtolower($text)));
    if($bytes===false){throw new RuntimeException('Validated UUID conversion failed');}
    return new MongoDB\BSON\Binary($bytes,MongoDB\BSON\Binary::TYPE_UUID);
}
$text='00112233-4455-4677-8899-aabbccddeeff';$uuid=uuid126($text);
bv126Insert($manager,$namespace,[['_id'=>201,'order_uuid'=>$uuid,'total_kopecks'=>4500]]);
$wrong=bv126Read($manager,$namespace,['order_uuid'=>$text],['_id'=>1],1);
$right=bv126Read($manager,$namespace,['order_uuid'=>uuid126(strtoupper($text))],['_id'=>1,'order_uuid'=>1,'total_kopecks'=>1],1);
$badForm=false;try{uuid126('00112233-wrong');}catch(InvalidArgumentException){$badForm=true;}
$badBytes=false;try{new MongoDB\BSON\Binary('short',MongoDB\BSON\Binary::TYPE_UUID);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$badBytes=true;}
$rows=[['Строка UUID',count($wrong),'совпадения нет'],['Binary subtype 4',count($right),'заказ '.$right[0]['_id'].', 4500 коп.'],
    ['Неверный текст отклонён',$badForm,'до запроса'],['UUID из 5 байт отклонён',$badBytes,'конструктором Binary']];
$checks=['typed_query_selected_order'=>array_column($right,'_id')===[201],'text_query_misses'=>$wrong===[],
    'uuid_16_bytes'=>bv126Summary($right[0]['order_uuid'])===['subtype'=>4,'bytes'=>16,'hex'=>'00112233445546778899aabbccddeeff'],
    'form_rejected'=>$badForm,'bad_binary_length_rejected'=>$badBytes,'order_amount'=>$right[0]['total_kopecks']===4500];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-uuid-lookup', ['Фильтр / проверка', 'Результат', 'Смысл'], $rows, $checks, $runtime);
echo 'mongodb126-binary-uuid-lookup: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-uuid-lookup: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Замените последнюю hex-цифру UUID только в фильтре. Верный по форме Binary вернёт пустой результат; это нормальное «заказ не найден», а не исключение конструктора.

Реальная постановка проблемы: Obtain UUID from MongoDB in PHP. Идентификатор, записанный Java как legacy Binary, не получается прочитать ожидаемой UUID-строкой простым base64/hex. Урок разделяет bytes, subtype и канонический текст; неизвестный Java byte order не исправляется выдуманным общим алгоритмом. Решение здесь самостоятельное; контракт API подтверждается официальными источниками, а обсуждение показывает, с чем сталкивается разработчик.

Различить одинаковые байты с разными BSON-подтипами

После переноса между системами UUID выглядят одинаково, но фильтр снова не находит запись. Нужно отделить содержимое байтов от метки их формата и понять, почему массово менять subtype 3 на 4 без знания источника опасно.

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

Три документа намеренно получают одинаковые 16 байтов, но разные подтипы: generic 0, legacy UUID 3 и current UUID 4. Их ID — 300, 303 и 304. Это контролируемая демонстрация типов, а не образец реальных Java/C#/Python архивов.

Как данные превращаются в результат
  1. Одинаковое содержимое: 00112233445546778899aabbccddeeff
  2. Три подписи: Binary subtype 0 / 3 / 4
  3. Три фильтра: каждый явно задаёт свой подтип
  4. Три результата: 300 / 303 / 304; подтипы не смешались

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

$bytes = hex2bin('00112233445546778899aabbccddeeff');
$legacy = new MongoDB\BSON\Binary($bytes, MongoDB\BSON\Binary::TYPE_OLD_UUID);
$standard = new MongoDB\BSON\Binary($bytes, MongoDB\BSON\Binary::TYPE_UUID);
echo $legacy->getType(), '/', $standard->getType(); // 3/4; bytes сами не переставляются

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

Результат выполнения

ПодтипБайтОдинаковые исходные bytesНайденный ID
01600112233445546778899aabbccddeeff300
31600112233445546778899aabbccddeeff303
41600112233445546778899aabbccddeeff304

Как это устроено

Binary — пара «байты + подтип». getType() возвращает вторую часть, getData() — первую. Подтип участвует в точном сравнении бинарного значения. Таблица показывает не три совпадения одного фильтра, а по одному совпадению каждого из трёх отдельных фильтров.

TYPE_OLD_UUID равен 3 и сохранён для совместимости. В разных старых драйверах порядок байтов UUID различался. PHP Binary не меняет его автоматически: при new Binary($bytes, 4) будут всё те же $bytes с другой меткой.

Общая функция bv126Summary принимает BinaryInterface и читает длину, hex и subtype. Это полезная граница кода: функция требует бинарное значение, но не обязана знать, относится оно к файлу, UUID или вектору. Интерфейс не добавляет функции getVectorType(), которой у его контракта нет.

Чтобы мигрировать исторические данные, сначала выясняют драйвер-производитель, соглашение UUID и сравнивают несколько известных идентификаторов. Только затем проектируют преобразование. Из таблицы нельзя вывести универсальное «перевернуть все байты».

Границы и типичные ошибки

Здесь одинаковые bytes специально заданы автором. В реальной миграции один логический UUID может иметь разные байты в старом и новом форматах. Подмена subtype не исправляет такую разницу. Для нового приложения выбирают subtype 4; legacy данные читают с их фактическим соглашением, не смешивая их с произвольными бинарными файлами.

Полная самостоятельная программа и архив
Различить одинаковые байты с разными BSON-подтипамиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$bytes=hex2bin('00112233445546778899aabbccddeeff');
$docs=[];foreach([0,3,4] as $type){$docs[]=['_id'=>300+$type,'label'=>'subtype '.$type,'identifier'=>new MongoDB\BSON\Binary($bytes,$type)];}
bv126Insert($manager,$namespace,$docs);$rows=[];$selected=[];$allSame=true;
foreach([0,3,4] as $type){
    $matches=bv126Read($manager,$namespace,['identifier'=>new MongoDB\BSON\Binary($bytes,$type)],['_id'=>1,'identifier'=>1],1);
    if(count($matches)!==1){throw new RuntimeException('Expected one match per subtype');}
    $binary=$matches[0]['identifier'];$summary=bv126Summary($binary);$selected[]=$matches[0]['_id'];
    $rows[]=[$summary['subtype'],$summary['bytes'],$summary['hex'],$matches[0]['_id']];$allSame=$allSame && (string)$binary===$bytes;
}
$checks=['subtype_changes_equality'=>$selected===[300,303,304],'all_raw_bytes_same'=>$allSame,
    'interface_supported'=>$docs[0]['identifier'] instanceof MongoDB\BSON\BinaryInterface,
    'old_uuid_exact_length'=>strlen($docs[1]['identifier']->getData())===16];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-uuid-subtypes', ['Подтип', 'Байт', 'Одинаковые исходные bytes', 'Найденный ID'], $rows, $checks, $runtime);
echo 'mongodb126-binary-uuid-subtypes: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-uuid-subtypes: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Поменяйте subtype только в фильтре 3 на 4. Вы получите документ 304, а не 303. Затем измените один байт: ни один из старых документов этому новому фильтру не соответствует.

Реальная постановка проблемы: Convert BinData type 3 data to type 4 in MongoDB. Разработчику нужен перевод всех UUID с subtype3 на4. Демонстрация показывает, почему одинаковые bytes с разными метками по-разному выбираются, и почему для реальной миграции нужен известный производитель и порядок байтов. Решение здесь самостоятельное; контракт API подтверждается официальными источниками, а обсуждение показывает, с чем сталкивается разработчик.

Передать бинарное поле через JSON без потери подтипа

Интеграция должна отправить двоичное поле текстовым JSON. Простое json_encode исходных bytes завершается ошибкой UTF-8, а незаметная потеря подтипа ломает последующий поиск UUID. Выберем явное представление и проверим обратный путь.

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

Из MongoDB читается payload из трёх байтов 41 00 FF. Полный пример сравнивает ошибочную сериализацию bytes, собственный JsonSerializable-контракт Binary и современный Canonical Extended JSON документа.

Как данные превращаются в результат
  1. Поле Binary: 41 00 FF, subtype 0
  2. Legacy JSON: {$binary: QQD/, $type: 00}
  3. Canonical JSON: {$binary: {base64: QQD/, subType: 00}}
  4. Document::fromJSON: снова Binary: 4100ff, subtype 0

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

$binary = new MongoDB\BSON\Binary("A\0\xFF");
echo json_encode($binary, JSON_THROW_ON_ERROR); // legacy Extended JSON
echo MongoDB\BSON\Document::fromPHP(['payload' => $binary])->toCanonicalExtendedJSON();

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

Результат выполнения

ОперацияДанные / результатПодтип / правило
JSON исходных bytesотклонён: не UTF-8не превращаем байты в текст
Binary::jsonSerializeQQD/00
Canonical Extended JSONQQD/00
После fromJSON4100ffsubtype 0

Как это устроено

Обычный JSON содержит текстовые строки Unicode и не имеет самостоятельного бинарного типа. Последовательность FF не является корректной UTF-8-строкой. JSON_THROW_ON_ERROR превращает проблему в JsonException; программа ловит только ожидаемый JSON_ERROR_UTF8.

Binary реализует JsonSerializable: json_encode($binary) автоматически вызывает его jsonSerialize(). Возвращаемое значение метода — структура, которую затем кодирует JSON, а не уже готовая строка JSON. Расширение выдаёт legacy Extended JSON: $binary содержит base64, $type — двухзначный hex-подтип.

Canonical Extended JSON использует другую вложенную форму: $binary содержит base64 и subType. Её явно получает Document::fromPHP(["payload" => $stored])->toCanonicalExtendedJSON(). Document сохраняет BSON-типы; обычный json_decode лишь даёт PHP-массив описания.

Восстановление BSON делает Document::fromJSON(), а get("payload") извлекает настоящий Binary. Проверяются bytes и subtype отдельно. Escape слеша в строке JSON может выглядеть по-разному; мы сравниваем декодированную структуру и значение, а не оформление пробелов.

Границы и типичные ошибки

Не смешивайте legacy Extended JSON с Canonical в одном неописанном протоколе. Передача base64 без subtype допустима только при отдельном договорённом типе поля. Base64 увеличивает текстовое представление и не защищает секреты. Для HTTP API можно выбрать собственный объект {encoding, subtype, data}, если обе стороны явно знают его контракт.

Полная самостоятельная программа и архив
Передать бинарное поле через JSON без потери подтипаСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$original=new MongoDB\BSON\Binary("A\0\xFF",MongoDB\BSON\Binary::TYPE_GENERIC);
bv126Insert($manager,$namespace,[['_id'=>401,'payload'=>$original]]);
$stored=bv126Read($manager,$namespace,['_id'=>401],['_id'=>0,'payload'=>1],1)[0]['payload'];
$rawRejected=false;try{json_encode($stored->getData(),JSON_THROW_ON_ERROR);}catch(JsonException $e){if($e->getCode()!==JSON_ERROR_UTF8){throw $e;}$rawRejected=true;}
$legacy=$stored->jsonSerialize();$encoded=json_encode($stored,JSON_THROW_ON_ERROR);$decodedLegacy=json_decode($encoded,true,512,JSON_THROW_ON_ERROR);
$document=MongoDB\BSON\Document::fromPHP(['payload'=>$stored]);$canonical=$document->toCanonicalExtendedJSON();
$visible=json_decode($canonical,true,512,JSON_THROW_ON_ERROR)['payload']['$binary'];
$roundtrip=MongoDB\BSON\Document::fromJSON($canonical)->get('payload');
$rows=[['JSON исходных bytes','отклонён: не UTF-8','не превращаем байты в текст'],
    ['Binary::jsonSerialize',$legacy['$binary'],$legacy['$type']],
    ['Canonical Extended JSON',$visible['base64'],$visible['subType']],
    ['После fromJSON',bin2hex($roundtrip->getData()),'subtype '.$roundtrip->getType()]];
$checks=['raw_non_utf8_rejected'=>$rawRejected,'legacy_shape'=>$legacy===['$binary'=>'QQD/','$type'=>'00'],
    'json_encode_uses_serializer'=>$decodedLegacy===$legacy,'canonical_shape'=>$visible===['base64'=>'QQD/','subType'=>'00'],
    'canonical_binary_roundtrip'=>$roundtrip instanceof MongoDB\BSON\Binary && $roundtrip->getData()===$stored->getData() && $roundtrip->getType()===$stored->getType()];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-binary-json', ['Операция', 'Данные / результат', 'Подтип / правило'], $rows, $checks, $runtime);
echo 'mongodb126-binary-binary-json: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-binary-json: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Повторите опыт с 16 байтами UUID subtype 4. Base64 будет другой, subType должен остаться 04, а после fromJSON поле должно снова подходить для бинарного UUID-фильтра.

Реальная постановка проблемы: What does the 0 mean in MongoDB BinData?. Видимый shell-вывод объединяет номер подтипа и base64, из-за чего их легко принять за сами bytes. Урок отличает бинарное содержимое, метку и две JSON-формы. Решение здесь самостоятельное; контракт API подтверждается официальными источниками, а обсуждение показывает, с чем сталкивается разработчик.

Сохранить два числовых признака и увидеть округление Float32

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

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

Два вручную заданных признака: доля заполнения 0.1 и масса 1.5 кг. Соглашение manual-features-v1 определяет их порядок, dimensions равно 2. Это обычные учебные числа; они не выдаются за результат нейросети.

Как данные превращаются в результат
  1. PHP список: [0.1, 1.5]: два double
  2. fromVector Float32: subtype 9; metadata 27 00; два числа по 4 байта
  3. MongoDB: features + model_version + dimensions
  4. toArray: 0.10000000149011612 и 1.5

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

$features = MongoDB\BSON\Binary::fromVector([0.1, 1.5], MongoDB\BSON\VectorType::Float32);
$numbers = $features->toArray(); // [0.10000000149011612, 1.5]
echo $features->getVectorType()->name; // Float32

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

Результат выполнения

ПризнакPHP double до записиFloat32 после чтенияФормат
Доля заполнения0.10000000000.1000000015Float32
Масса, кг1.50000000001.5000000000Float32

Как это устроено

Вектор в этой главе — упорядоченный список однотипных значений. Он полезен, когда схема уже говорит, что означает каждая позиция. Binary::fromVector() — статический метод: :: вызывает его у класса без предварительного new Binary. Второй аргумент — случай enum VectorType, а не строка "Float32".

PHP float обычно представляет double, а выбранный формат хранит только 32 бита на компоненту. 0.1 не представляется точно и в double, и в Float32; после сужения мы видим дополнительное отличие. 1.5 в этих форматах представляется точно. number_format задаёт ровно десять цифр после точки для понятной таблицы.

getType() возвращает 9 — общую BSON-метку вектора. getVectorType() возвращает объект enum Float32, Int8 или PackedBit. Его name — читаемая подпись; у этого enum нет свойства value с числовым кодом. toArray() распаковывает компоненты обратно в PHP-массив.

fromVector требует настоящие float для Float32: [1] с целым int не принимается, [1.0] подходит. Числовую строку из формы нужно отдельно проверить и преобразовать, а не надеяться на неявную догадку бинарного кодека.

Границы и типичные ошибки

Этот формат не подходит для точных денег: используйте целые копейки или Decimal128. Не сравнивайте произвольные вычисленные Float32 строгим === с исходными double; выбирайте обоснованную погрешность задачи. Формат не обучает модель, не строит индекс и не обеспечивает similarity search. Названия и единицы признаков должны быть закреплены вашей схемой.

Полная самостоятельная программа и архив
Сохранить два числовых признака и увидеть округление Float32Самостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$input=[0.1,1.5];$binary=MongoDB\BSON\Binary::fromVector($input,MongoDB\BSON\VectorType::Float32);
bv126Insert($manager,$namespace,[['_id'=>501,'model_version'=>'manual-features-v1','dimensions'=>2,'features'=>$binary]]);
$doc=bv126Read($manager,$namespace,['_id'=>501],['_id'=>1,'features'=>1,'model_version'=>1,'dimensions'=>1],1)[0];
$stored=$doc['features'];$values=$stored->toArray();$rows=[];
foreach(['Доля заполнения','Масса, кг'] as $i=>$label){$rows[]=[$label,number_format($input[$i],10,'.',''),number_format($values[$i],10,'.',''),$stored->getVectorType()->name];}
$integerRejected=false;try{MongoDB\BSON\Binary::fromVector([1],MongoDB\BSON\VectorType::Float32);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$integerRejected=true;}
$checks=['vector_subtype'=>$stored->getType()===MongoDB\BSON\Binary::TYPE_VECTOR,'float32_format'=>$stored->getVectorType()===MongoDB\BSON\VectorType::Float32,
    'one_value_rounded'=>$values[0]!==$input[0] && abs($values[0]-$input[0])<0.00000001,'exact_half'=>$values[1]===1.5,
    'two_float_values'=>count($values)===2 && is_float($values[0]) && is_float($values[1]),'int_not_implicitly_float'=>$integerRejected,
    'payload_header_and_values'=>bin2hex($stored->getData())==='2700cdcccc3d0000c03f','schema_retained'=>$doc['dimensions']===2 && $doc['model_version']==='manual-features-v1'];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-vector-float32', ['Признак', 'PHP double до записи', 'Float32 после чтения', 'Формат'], $rows, $checks, $runtime);
echo 'mongodb126-binary-vector-float32: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-vector-float32: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Замените 0.1 на 0.25. Для обеих компонент сравнение с исходными числами станет точным. Затем попробуйте [1, 1.5] и объясните, почему первый элемент надо записать как 1.0.

Хранить калибровочные поправки в Int8 с явными единицами

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

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

Поправки в минимальных единицах: -128, 0, 127. Поле unit задаёт 0.1 C; следовательно, таблица должна показать -12.8, 0.0 и 12.7 °C. Намеренные неверные значения 128 и -129 не записываются.

Как данные превращаются в результат
  1. Договорённость: одно целое = 0.1 °C
  2. Int8 список: [-128, 0, 127]
  3. Binary: 03 00 + 80 00 7F: 5 байтов payload
  4. Экран: -12.8 °C / 0.0 °C / 12.7 °C

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

$offsets = MongoDB\BSON\Binary::fromVector([-128, 0, 127], MongoDB\BSON\VectorType::Int8);
echo bin2hex($offsets->getData()); // 030080007f: metadata + три signed int8
$values = $offsets->toArray(); // [-128, 0, 127]; масштаб выбирает приложение

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

Результат выполнения

ПозицияСохранённое целоеПоправка по scale 0.1Формат
Датчик 1-128-12.8 °CInt8
Датчик 200.0 °CInt8
Датчик 312712.7 °CInt8

Как это устроено

Int8 — знаковое восьмибитное целое с диапазоном от -128 до 127. Один байт даёт 256 комбинаций: половина отрицательных, ноль и положительные. Верхняя граница 128 не входит. В текущем тексте PHP.net встречается опечатка -127..128; официальный BSON vector specification и работа расширения задают signed 8-bit диапазон -128..127.

Масштаб не встроен в Binary. Мы сами храним unit и сами делим прочитанное целое на 10 при отображении. Если другой потребитель применит иной масштаб, байты сохранятся верно, но смысл результата станет неверным.

Пять байтов в таблице проверки — два байта vector metadata и три компоненты. Это не полный размер BSON-документа: имена полей, _id и другие данные тоже занимают место. Для маленького примера не делается заявление о скорости или общем экономическом выигрыше.

Проверки крайних значений ловят InvalidArgumentException у конкретного fromVector. В реальном импорте следует сообщить пользователю номер неверной строки и не молча обрезать 128 до 127: такая правка изменила бы измерение.

Границы и типичные ошибки

Int8 имеет смысл только при заранее согласованных диапазоне, единицах и масштабе. Для более широких значений выбирайте другой формат или обычные числовые поля. Квантизация с округлением — отдельное бизнес-правило; fromVector её за вас не выполняет. Binary не является удобным полем для произвольной серверной фильтрации по отдельной компоненте.

Полная самостоятельная программа и архив
Хранить калибровочные поправки в Int8 с явными единицамиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$input=[-128,0,127];$binary=MongoDB\BSON\Binary::fromVector($input,MongoDB\BSON\VectorType::Int8);
bv126Insert($manager,$namespace,[['_id'=>601,'unit'=>'0.1 C','model_version'=>'calibration-v1','offsets'=>$binary]]);
$doc=bv126Read($manager,$namespace,['_id'=>601],['_id'=>1,'unit'=>1,'offsets'=>1],1)[0];$stored=$doc['offsets'];$values=$stored->toArray();
$rows=[];foreach($values as $i=>$n){$rows[]=['Датчик '.($i+1),$n,number_format($n/10,1,'.','').' °C',$stored->getVectorType()->name];}
$tooHigh=false;$tooLow=false;
try{MongoDB\BSON\Binary::fromVector([128],MongoDB\BSON\VectorType::Int8);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$tooHigh=true;}
try{MongoDB\BSON\Binary::fromVector([-129],MongoDB\BSON\VectorType::Int8);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$tooLow=true;}
$checks=['int8_values_exact'=>$values===$input,'int8_format'=>$stored->getVectorType()===MongoDB\BSON\VectorType::Int8,
    'payload_five_bytes'=>bv126Summary($stored)===['subtype'=>9,'bytes'=>5,'hex'=>'030080007f'],
    'upper_boundary_rejected'=>$tooHigh,'lower_boundary_rejected'=>$tooLow,'unit_selected'=>$doc['unit']==='0.1 C'];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-vector-int8', ['Позиция', 'Сохранённое целое', 'Поправка по scale 0.1', 'Формат'], $rows, $checks, $runtime);
echo 'mongodb126-binary-vector-int8: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-vector-int8: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Добавьте поправку 5: на экране это 0.5 °C, payload увеличится с 5 до 6 байтов. Значение 130 надо отклонить или изменить схему хранения; превращать его в 127 без объяснения нельзя.

Упаковать десять флагов комплектации и восстановить подписи

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

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

Список признаков equipment-v1: USB-C, HDMI, Wi-Fi, Ethernet, Bluetooth, NFC, SD, SIM, камера, микрофон. Вход смешивает bool и целые 0/1; после чтения ожидаются именно int 0/1 в прежнем порядке.

Как данные превращаются в результат
  1. Схема equipment-v1: индекс 0 = USB-C, 1 = HDMI, …, 9 = микрофон
  2. Десять битов: 1010101011
  3. Упаковка: 10 06 AA C0: тип, 6 бит заполнения, 2 байта данных
  4. Распаковка: 10 значений → названия → есть / нет

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

$flags = MongoDB\BSON\Binary::fromVector([true, false, 1, 0, 1, 0, 1, 0, 1, 1], MongoDB\BSON\VectorType::PackedBit);
echo bin2hex($flags->getData()); // 1006aac0
$bits = $flags->toArray(); // десять int 0/1, без шести битов заполнения

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

Результат выполнения

ИндексПризнакПрочитанный intНа карточке
0USB-C1есть
1HDMI0нет
2Wi-Fi1есть
3Ethernet0нет
4Bluetooth1есть
5NFC0нет
6SD1есть
7SIM0нет
8Камера1есть
9Микрофон1есть

Как это устроено

PackedBit сохраняет по одному полезному биту на значение. PHP-метод принимает список bool или int 0/1. Восстановленный массив содержит int, поэтому сравнение $value === 1 корректно даже для входного true.

Десять полезных битов занимают два байта. В последнем остаётся шесть младших битов заполнения. Metadata сообщает, сколько игнорировать: toArray возвращает десять значений, а не шестнадцать. В hex 1006aac0 первые 10 и 06 — байты формата и padding, не первые два пользовательских признака.

Отдельный массив labels превращает позицию в смысл. Флаг 1 сам по себе не означает «есть Wi-Fi», пока неизвестно, какой позиции соответствует Wi-Fi. Поэтому schema_version сохраняется вместе с Binary.

Значение 2 не является битом и вызывает InvalidArgumentException. Не нужно заранее паковать восемь признаков в число 0..255: такой API бывает в других драйверах, но PHP fromVector PackedBit ждёт отдельные биты.

Границы и типичные ошибки

Для обычных фильтруемых свойств каталога понятный массив строк или именованные bool-поля часто удобнее. PackedBit полезен для компактного фиксированного протокола; он не заменяет понятную схему. Не меняйте порядок labels без новой версии. Показываемые четыре байта — payload Binary с metadata, не размер всего документа.

Полная самостоятельная программа и архив
Упаковать десять флагов комплектации и восстановить подписиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$labels=['USB-C','HDMI','Wi-Fi','Ethernet','Bluetooth','NFC','SD','SIM','Камера','Микрофон'];
$input=[true,false,1,0,true,false,1,0,1,1];$bits=MongoDB\BSON\Binary::fromVector($input,MongoDB\BSON\VectorType::PackedBit);
bv126Insert($manager,$namespace,[['_id'=>701,'schema_version'=>'equipment-v1','flags'=>$bits]]);
$stored=bv126Read($manager,$namespace,['_id'=>701],['_id'=>1,'flags'=>1,'schema_version'=>1],1)[0];$binary=$stored['flags'];$values=$binary->toArray();
$rows=[];foreach($values as $i=>$value){$rows[]=[$i,$labels[$i],$value,$value===1?'есть':'нет'];}
$bad=false;try{MongoDB\BSON\Binary::fromVector([2],MongoDB\BSON\VectorType::PackedBit);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$bad=true;}
$checks=['ten_values_with_positions'=>$values===[1,0,1,0,1,0,1,0,1,1],
    'packedbit_format'=>$binary->getVectorType()===MongoDB\BSON\VectorType::PackedBit,
    'two_payload_bytes_plus_header'=>bv126Summary($binary)===['subtype'=>9,'bytes'=>4,'hex'=>'1006aac0'],
    'output_integers'=>array_filter($values,fn($v)=>!is_int($v))===[],'invalid_bit_rejected'=>$bad,'schema_version_preserved'=>$stored['schema_version']==='equipment-v1'];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-vector-packed-bits', ['Индекс', 'Признак', 'Прочитанный int', 'На карточке'], $rows, $checks, $runtime);
echo 'mongodb126-binary-vector-packed-bits: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-vector-packed-bits: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Добавьте одиннадцатый флаг «GPS» со значением 0 в конец схемы. Полезных битов станет 11, padding — 5; toArray должен вернуть ровно 11 значений. Для изменённой схемы задайте новую версию.

Проверить формат, размерность и конечность чисел до сохранения

Интеграция присылает числовой профиль товара. Технически кодек умеет хранить много форм данных, но вашему сервису нужны ровно три конечных Float32 в фиксированном порядке. Отделим ограничения API от требований приложения.

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

Шесть неверных входов: пропуски ключей, пустота, две компоненты, строка, INF и конечное double 1e100. Корректный профиль [0.25, 0.5, 0.75] должен стать единственной записью 801. Отдельно проверяется ошибочное чтение обычного Binary как вектора.

Как данные превращаются в результат
  1. Вход интеграции: PHP массив, ещё не доверенный профиль
  2. Контракт приложения: list + 3 float + finite + диапазон Float32
  3. fromVector: только проверенный профиль
  4. Запись и чтение: ID 801; остальные входы не попали в базу

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

$values = [0.25, 0.5, 0.75];
if (!array_is_list($values) || count($values) !== 3) {
    throw new InvalidArgumentException('Нужны три упорядоченных признака');
}
$binary = MongoDB\BSON\Binary::fromVector($values, MongoDB\BSON\VectorType::Float32);

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

Результат выполнения

ВходРезультатПричина / сохранение
Пропуски ключейотклонёнlist_required
Пустой профильотклонёнdimensions_3_required
Две компонентыотклонёнdimensions_3_required
Строка вместо числаотклонёнfinite_float_required
Бесконечностьотклонёнfinite_float_required
Конечное, но слишком большоеотклонёнfloat32_range_required
Корректный профильзаписанID 801, 3 компоненты
Обычный Binaryне вектор2 LogicException

Как это устроено

array_is_list проверяет последовательные ключи 0..n-1, а count — нужное число компонент. Пропуски могут возникнуть после array_filter. Не применяйте array_values автоматически, пока не ясно, что исчезновение позиции допустимо: оно может сместить смысл признаков.

is_float исключает строки и целые, is_finite исключает NAN и INF. Но конечное PHP double 1e100 всё ещё больше наибольшего конечного Float32. Поэтому приложение отдельно ограничивает модуль значением 3.4028234663852886e38 до кодирования.

Пустой список fromVector принимает и сохраняет только два байта metadata. Наш profile126 отклоняет его, потому что пустота не является товарным профилем из трёх признаков. Это предметное решение, а не приписанное библиотеке ограничение.

getVectorType и toArray для Binary generic бросают LogicException: они не возвращают null и не угадывают содержимое строки. В полном опыте оба неверных вызова происходят реально и ловятся только ожидаемым типом исключения.

Запись выполняется после всех проверок; Query показывает только один корректный документ. Сообщения list_required и dimensions_3_required — короткие коды нашей валидации. Интерфейс приложения может переводить их в понятные подписи.

Границы и типичные ошибки

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

Полная самостоятельная программа и архив
Проверить формат, размерность и конечность чисел до сохраненияСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
function profile126(array $values): MongoDB\BSON\Binary {
    if(!array_is_list($values)){throw new InvalidArgumentException('list_required');}
    if(count($values)!==3){throw new InvalidArgumentException('dimensions_3_required');}
    foreach($values as $n){
        if(!is_float($n) || !is_finite($n)){throw new InvalidArgumentException('finite_float_required');}
        if(abs($n)>3.4028234663852886e38){throw new InvalidArgumentException('float32_range_required');}
    }
    return MongoDB\BSON\Binary::fromVector($values,MongoDB\BSON\VectorType::Float32);
}
$cases=[['Пропуски ключей',[0=>1.0,2=>2.0,3=>3.0],'list_required'],['Пустой профиль',[],'dimensions_3_required'],
    ['Две компоненты',[1.0,2.0],'dimensions_3_required'],['Строка вместо числа',[1.0,'2.0',3.0],'finite_float_required'],
    ['Бесконечность',[1.0,INF,3.0],'finite_float_required'],['Конечное, но слишком большое',[1.0,1e100,3.0],'float32_range_required']];$rows=[];$rejected=0;
foreach($cases as [$label,$input,$expected]){try{profile126($input);throw new RuntimeException('Invalid profile accepted');}
    catch(InvalidArgumentException $e){if($e->getMessage()!==$expected){throw $e;}$rejected++;$rows[]=[$label,'отклонён',$expected];}}
$empty=MongoDB\BSON\Binary::fromVector([],MongoDB\BSON\VectorType::Float32);
$nonvector=new MongoDB\BSON\Binary('plain');$logicErrors=0;
foreach(['getVectorType','toArray'] as $method){try{$nonvector->$method();throw new RuntimeException('Non-vector accepted');}catch(MongoDB\Driver\Exception\LogicException){$logicErrors++;}}
$sparse=false;try{MongoDB\BSON\Binary::fromVector([0=>1,2=>2],MongoDB\BSON\VectorType::Int8);}catch(MongoDB\Driver\Exception\InvalidArgumentException){$sparse=true;}
$good=profile126([0.25,0.5,0.75]);bv126Insert($manager,$namespace,[['_id'=>801,'dimensions'=>3,'features'=>$good]]);
$docs=bv126Read($manager,$namespace,[],['_id'=>1,'features'=>1,'dimensions'=>1],10);
$rows[]=['Корректный профиль','записан','ID '.$docs[0]['_id'].', 3 компоненты'];
$rows[]=['Обычный Binary','не вектор','2 LogicException'];
$checks=['six_invalid_profiles_rejected'=>$rejected===6,'only_valid_record_saved'=>array_column($docs,'_id')===[801],
    'values_preserved'=>$docs[0]['features']->toArray()===[0.25,0.5,0.75],'empty_allowed_by_codec'=>count($empty->toArray())===0 && strlen($empty->getData())===2,
    'nonvector_access_rejected'=>$logicErrors===2,'sparse_list_rejected_by_driver'=>$sparse];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-vector-validation', ['Вход', 'Результат', 'Причина / сохранение'], $rows, $checks, $runtime);
echo 'mongodb126-binary-vector-validation: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-vector-validation: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Измените dimensions на 4 и добавьте четвёртый признак. Правильное решение меняет проверку длины, схему и версию одновременно; изменение только count оставит потребителям непонятную четвёртую позицию.

Сначала показать карточки, затем получить только выбранные векторы

Список товаров должен открываться без ненужных двоичных полей. Числовые признаки нужны только после выбора двух конкретных товаров для внешнего расчёта. Пусть база вернёт ровно нужные записи и поля.

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

В коллекции три карточки: Кабель 901 и Зарядка 903 с features-v2, Чехол 902 со старой features-v1. Первый Query выбирает заголовки и версию; второй выбирает только ID 901/903, features-v2 и dimensions=3.

Как данные превращаются в результат
  1. Список каталога: 3 строки: ID, название, версия; без features
  2. Выбор пользователя: 901 и 903; нужна features-v2
  3. Query с условиями: _id $in + model_version + dimensions + projection + limit
  4. Ответ API: только два списка чисел + формат + схема

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

$filter = ['_id' => ['$in' => [901, 903]], 'model_version' => 'features-v2', 'dimensions' => 3];
$options = ['projection' => ['_id' => 1, 'features' => 1, 'model_version' => 1, 'dimensions' => 1], 'limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options); // выбираем нужное на сервере

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

Результат выполнения

ID выбранного товараВерсия признаковФорматЧисла для клиентаБайт Binary payload
901features-v2Float320.25, 0.50, 0.7514
903features-v2Float320.75, 0.50, 0.2514

Как это устроено

projection перечисляет поля на стороне MongoDB: тяжёлое features не передаётся для общего экрана. PHP не получает все векторы, чтобы потом выбросить их. sort делает порядок ожидаемым, limit ограничивает число документов; batchSize не подменяет этот предел.

Второй фильтр одновременно проверяет выбранные ID, версию модели и размерность. Две одинаково длинные последовательности разных моделей не становятся совместимыми только из-за длины. ID 902 не попадает в экспорт.

Перед распаковкой читается getVectorType. Потребителю нужны числа, поэтому API получает явный объект с id, model, dimensions, format и values. Это наш предметный JSON-контракт, а не попытка скрытно превратить Binary в обычный массив.

В учебном опыте собираются ровно две небольшие строки. Если задача — экспорт многих документов, применяют последовательное чтение курсора и запись результата по частям. Для реального пользователя также добавляется фильтр tenant/owner и серверный предел разрешённых ID.

Границы и типичные ошибки

Это загрузка выбранных признаков для отдельного расчёта, а не поиск ближайших векторов. Здесь нет модели, Atlas, vectorSearch или оценки качества рекомендаций. Число байтов относится к одному Binary payload. Измерения скорости на таком маленьком наборе не давали бы оснований обещать ускорение production.

Полная самостоятельная программа и архив
Сначала показать карточки, затем получить только выбранные векторыСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/bv126-helper.php';
$settings=bv126Settings();$database=$settings['database'];
$manager=new MongoDB\Driver\Manager($settings['uri'],['serverSelectionTimeoutMS'=>1500,'connectTimeoutMS'=>500,'socketTimeoutMS'=>2000,'retryReads'=>false]);
$owned=[];
try{
$version=bv126Command($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=bv126Create($manager,$database,$owned);
$seed=[[901,'Кабель','features-v2',[0.25,0.5,0.75]],[902,'Чехол','features-v1',[0.5,0.5,0.5]],[903,'Зарядка','features-v2',[0.75,0.5,0.25]]];$docs=[];
foreach($seed as [$id,$title,$versionName,$features]){$docs[]=['_id'=>$id,'title'=>$title,'model_version'=>$versionName,'dimensions'=>3,
    'features'=>MongoDB\BSON\Binary::fromVector($features,MongoDB\BSON\VectorType::Float32),'internal_note'=>'не для клиента'];}
bv126Insert($manager,$namespace,$docs);
$cards=bv126Read($manager,$namespace,[],['_id'=>1,'title'=>1,'model_version'=>1],3);
$selected=bv126Read($manager,$namespace,['_id'=>['$in'=>[901,903]],'model_version'=>'features-v2','dimensions'=>3],['_id'=>1,'features'=>1,'model_version'=>1,'dimensions'=>1],2);
$rows=[];$export=[];$allTypes=true;
foreach($selected as $doc){$binary=$doc['features'];$allTypes=$allTypes && $binary->getVectorType()===MongoDB\BSON\VectorType::Float32;
    $values=$binary->toArray();$summary=bv126Summary($binary);
    $export[]=['id'=>$doc['_id'],'model'=>$doc['model_version'],'dimensions'=>$doc['dimensions'],'format'=>$binary->getVectorType()->name,'values'=>$values];
    $rows[]=[$doc['_id'],$doc['model_version'],$binary->getVectorType()->name,implode(', ',array_map(fn($v)=>number_format($v,2,'.',''),$values)),$summary['bytes']];}
$api=json_encode($export,JSON_THROW_ON_ERROR);$decoded=json_decode($api,true,512,JSON_THROW_ON_ERROR);
$checks=['screen_three_metadata_rows'=>array_column($cards,'_id')===[901,902,903],
    'screen_does_not_fetch_vectors'=>array_filter($cards,fn($d)=>array_key_exists('features',$d)||array_key_exists('internal_note',$d))===[],
    'selected_model_only'=>array_column($selected,'_id')===[901,903],'selected_format_float32'=>$allTypes,
    'explicit_api_values'=>$decoded[0]['values']===[0.25,0.5,0.75] && $decoded[1]['values']===[0.75,0.5,0.25],
    'export_has_model_and_dimensions'=>$decoded[0]['model']==='features-v2' && $decoded[0]['dimensions']===3];
}finally{
    foreach(array_reverse($owned) as $name){bv126Command($manager,$database,['drop'=>$name],true);}
}
$removed=true;foreach($owned as $name){if(bv126Exists($manager,$database,$name)){$removed=false;}}
$checks['only_owned_collections_removed']=$removed && count($owned)===1;
bv126Report('mongodb126-binary-selected-vector-export', ['ID выбранного товара', 'Версия признаков', 'Формат', 'Числа для клиента', 'Байт Binary payload'], $rows, $checks, $runtime);
echo 'mongodb126-binary-selected-vector-export: saved result.html and result.json
';
Ожидаемый результат
mongodb126-binary-selected-vector-export: saved result.html and result.json

Реальные запись и чтение MongoDB; HTML/JSON показывают прочитанные данные. В архив включены helper и README, проверка ожидаемых отказов и очистка только собственных ресурсов.

Открыть фактический результат · JSON таблицы

Попробуйте изменить. Выберите [901, 902], сохранив условие features-v2. Вернётся только 901. Интерфейс должен сообщить, что второй товар использует другую версию, а не молча сравнивать несовместимые профили.

Как выбрать представление для текущей задачи

Нужно сделатьИнструментЧто обязательно сохранить
Сохранить небольшой двоичный фрагментBinary(bytes, TYPE_GENERIC)Исходные bytes; нужные метаданные файла отдельно
Найти заказ по UUID формыПроверка текста → hex2bin → Binary TYPE_UUID16 байтов и именно тот subtype, который хранится
Прочитать legacy UUIDgetData + getType и известное соглашение производителяПорядок байтов; не менять 3 на 4 вслепую
Передать Binary в JSONЯвный Extended JSON либо согласованный APIBase64 плюс subtype; не только видимый текст
Упаковать однотипные признакиfromVector + VectorTypeПорядок, размерность, версию схемы, единицы
Показать общий список товаровQuery с projection и limitТолько поля для текущего экрана
Распаковать выбранный профильgetVectorType → toArrayПроверенный формат и предметный диапазон

Полный справочник Binary, BinaryInterface и VectorType

Сводка Binary сохраняет все константы и методы класса. Каждая карточка раскрывает сигнатуру, параметры, результат, ошибки, версии и два содержательно разных применения. Ссылки ведут к тем же девяти реальным программам, а не к искусственно размноженным копиям.

APIПрактическое назначение
MongoDB\BSON\BinaryХранить байты вместе с BSON-подтипом: от фрагмента файла и UUID до компактного вектора.
MongoDB\BSON\Binary::__constructСоздать бинарное поле из исходной строки bytes, явно выбрав формат.
MongoDB\BSON\Binary::fromVectorУпаковать список чисел или битов в Binary subtype 9, сохранив явный формат элементов.
MongoDB\BSON\Binary::getDataПрочитать исходные bytes для файла, проверки целостности или просмотра формата.
MongoDB\BSON\Binary::getTypeУзнать BSON-подтип перед выбором преобразования или совместимого фильтра.
MongoDB\BSON\Binary::getVectorTypeПрочитать формат компонент настоящего вектора перед использованием чисел.
MongoDB\BSON\Binary::jsonSerializeПолучить legacy Extended JSON представление бинарного значения без не-UTF-8 в строке JSON.
MongoDB\BSON\Binary::toArrayРаспаковать бинарный вектор в числовой список для расчёта или понятного экрана.
MongoDB\BSON\Binary::__toStringИспользовать бинарное значение там, где нужен исходный поток bytes.
MongoDB\BSON\BinaryInterfaceОбъявить понятный тип параметра, возвращаемого значения или свойства для двоичных данных.
MongoDB\BSON\BinaryInterface::getDataЗафиксировать в типизированном помощнике контракт получения исходных bytes.
MongoDB\BSON\BinaryInterface::getTypeСохранить метку двоичного формата в общей функции, не теряя её при чтении bytes.
MongoDB\BSON\BinaryInterface::__toStringОписать строковое приведение как чтение bytes, а не как готовое оформление для пользователя.
MongoDB\BSON\VectorTypeЯвно выбрать формат компонент вектора и прочитать тот же формат после MongoDB.

Закрепить формат и переходить к следующей задаче

Теперь можно выбрать представление по задаче: хранить bytes без потерь, искать UUID с правильным типом, переносить типизированное поле через JSON и получать только нужные векторы. Следующее действие — закрепить формат собственного поля: кто его создаёт, как проверяются входные данные и какие сведения нужны получателю.

Продолжение: Regex для отбора текстовых документов; даты, ObjectId и точные Decimal128; BSON Document и Extended JSON; постраничное чтение и экспорт без накопления всех строк.

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

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

MongoDB\BSON\BinaryХранить байты вместе с BSON-подтипом: от фрагмента файла и UUID до компактного вектора.

mongodb 1.0.0; версии расширений — в карточке · mongodb

final class MongoDB\BSON\Binary implements MongoDB\BSON\BinaryInterface,
    MongoDB\BSON\Type, JsonSerializable, Stringable {
    final public function __construct(string $data, int $type = self::TYPE_GENERIC);
    final public static function fromVector(array $vector, MongoDB\BSON\VectorType $vectorType): MongoDB\BSON\Binary;
    final public function getData(): string;
    final public function getType(): int;
    final public function getVectorType(): MongoDB\BSON\VectorType;
    final public function jsonSerialize(): mixed;
    final public function toArray(): array;
    final public function __toString(): string;
}

Хранить байты вместе с BSON-подтипом: от фрагмента файла и UUID до компактного вектора.

Сигнатура и базовый контракт

final class MongoDB\BSON\Binary implements MongoDB\BSON\BinaryInterface,
    MongoDB\BSON\Type, JsonSerializable, Stringable {
    final public function __construct(string $data, int $type = self::TYPE_GENERIC);
    final public static function fromVector(array $vector, MongoDB\BSON\VectorType $vectorType): MongoDB\BSON\Binary;
    final public function getData(): string;
    final public function getType(): int;
    final public function getVectorType(): MongoDB\BSON\VectorType;
    final public function jsonSerialize(): mixed;
    final public function toArray(): array;
    final public function __toString(): string;
}
Вход / вариантЗначение и ограничение
data / typeДля общего конструктора: исходные bytes и подтип 0..255. Никакого обязательного base64 на входе.
vector / vectorTypeДля фабрики fromVector: список компонент и один из трёх случаев VectorType.

Что получит вызывающий код

Экземпляр BSON Binary содержит две части: неизменённые исходные bytes и метку подтипа. При записи документа драйвер кодирует его как BSON binary; при обычном чтении это снова Binary. Публичные свойства данных класс не объявляет, чтение выполняется методами.

Ошибки

Наследоваться от final-класса нельзя. Ограничения аргументов определяются конструктором/фабрикой; специальные векторные чтения неприменимы к обычным подтипам и бросают LogicException. Создание объекта само по себе не обращается к MongoDB и не проверяет права записи.

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

Класс с 1.0.0. JsonSerializable и прежний Serializable добавлялись в 1.2.0; BinaryInterface — 1.3.0. TYPE_ENCRYPTED — 1.7.0. TYPE_COLUMN и Stringable для PHP 8+ — 1.12.0. TYPE_SENSITIVE — 1.17.0. В 2.0.0 реализация Serializable удалена. TYPE_VECTOR и векторные методы — 2.2.0. У актуального класса восемь методов, перечисленных в сигнатуре.

КонстантаЧислоЧто означает и чего не делает
TYPE_GENERIC0Произвольные bytes; обычный выбор для небольшого двоичного поля.
TYPE_FUNCTION1Историческая метка function; не выполняет PHP-код и не сериализует callable.
TYPE_OLD_BINARY2Устаревшая двоичная форма; новым данным предпочтителен TYPE_GENERIC.
TYPE_OLD_UUID3Исторический UUID, ровно 16 байтов; порядок зависит от прежнего производителя.
TYPE_UUID4UUID в стандартном RFC 4122 порядке, ровно 16 байтов; PHP не переставляет bytes автоматически.
TYPE_MD55Метка 16-байтового MD5-значения; не вычисляет хеш и не делает его пригодным для защиты паролей.
TYPE_ENCRYPTED6Служебный payload клиентского шифрования; выбор числа 6 не шифрует bytes.
TYPE_COLUMN7Служебное колонночное представление для time series; не обычный пользовательский массив.
TYPE_SENSITIVE8Метка чувствительных данных для ограничения журналирования, где поддерживается; не шифрование и не гарантия отсутствия всех логов.
TYPE_VECTOR9Компактный числовой/битовый вектор с metadata о формате.
TYPE_USER_DEFINED128Начало диапазона пользовательских подтипов 128..255; соглашение задаёт приложение.

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

Архивировать двоичный фрагмент датчика

Binary сохраняет NUL и FF; после Query проверяются шесть исходных байтов и SHA256. Получатель видит безопасный hex, а не повреждённый текст.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Найти заказ по типизированному идентификатору

Те же возможности класса применяются к 16 байтам subtype 4: текст формы становится правильным бинарным фильтром, который выбирает заказ 201.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Подтипы 0..127 предопределены или зарезервированы, 128..255 пользовательские. Не присваивайте зарезервированному номеру собственный смысл. UUID subtype 3 может иметь исторический порядок байтов; PHP не исправляет его автоматически. Метка формата не превращает произвольное содержимое в корректный UUID, MD5, шифротекст или вектор.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::__constructСоздать бинарное поле из исходной строки bytes, явно выбрав формат.

mongodb 1.0.0; версии расширений — в карточке · mongodb

final public MongoDB\BSON\Binary::__construct(string $data, int $type = MongoDB\BSON\Binary::TYPE_GENERIC)

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

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::__construct(string $data, int $type = MongoDB\BSON\Binary::TYPE_GENERIC)
Вход / вариантЗначение и ограничение
data: stringИсходные bytes. PHP string может содержать NUL и не-UTF-8; не надо предварительно переводить в base64.
type: int = TYPE_GENERICБеззнаковый номер подтипа 0..255; по умолчанию 0. Для UUID 3 и 4 data должен содержать ровно 16 байтов.

Что получит вызывающий код

Конструктор инициализирует новый Binary. Выражение new возвращает созданный объект; собственный возвращаемый тип у __construct не указан. Записи в базу ещё нет.

Ошибки

MongoDB\Driver\Exception\InvalidArgumentException при неверных аргументах, подтипе вне 0..255 или неверной длине UUID. Как обычно, нарушение PHP-сигнатуры может быть ошибкой типов/арности. Программа не должна ловить все исключения подключения как ошибку UUID.

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

Метод с 1.0.0. Проверка unsigned 8-bit type действует с 1.1.3. Обязательные 16 байтов для subtype 3/4 — с 1.3.0. Значение TYPE_GENERIC по умолчанию добавлено в 1.15.0; в старом API type требовалось передать явно.

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

Сохранить содержимое файла

new Binary($bytes, TYPE_GENERIC) сохраняет весь шестибайтовый фрагмент, а не его base64-написание.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Преобразовать идентификатор заказа

После проверки текста hex2bin даёт ровно 16 байтов для TYPE_UUID; намеренные пять байтов приводят к ожидаемому отказу.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Строка с 36 символами UUID и строка с 32 hex-цифрами не являются 16 исходными байтами. hex2bin выполняет нужное преобразование после проверки формы. Binary не занимается автоматической перекодировкой UUID разных языков. Для вектора используйте fromVector, чтобы корректно сформировать metadata.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::fromVectorУпаковать список чисел или битов в Binary subtype 9, сохранив явный формат элементов.

mongodb 2.2.0 · mongodb

final public static MongoDB\BSON\Binary::fromVector(array $vector, MongoDB\BSON\VectorType $vectorType): MongoDB\BSON\Binary

Упаковать список чисел или битов в Binary subtype 9, сохранив явный формат элементов.

Сигнатура и базовый контракт

final public static MongoDB\BSON\Binary::fromVector(array $vector, MongoDB\BSON\VectorType $vectorType): MongoDB\BSON\Binary
Вход / вариантЗначение и ограничение
vector: arrayИменно список с ключами 0..n-1. Float32: каждый элемент float; Int8: каждый int от -128 до 127; PackedBit: bool или int 0/1. Тип и диапазон не угадываются по строке.
vectorType: VectorTypeОдин случай enum: Float32, Int8, PackedBit. Не строковое имя и не номер BSON-подтипа.

Что получит вызывающий код

Новый Binary с TYPE_VECTOR = 9. Метаданные формата входят в payload. toArray распаковывает его, getVectorType сообщает выбранный enum. Пустой список технически допустим; предметное требование непустой размерности проверяется отдельно.

Ошибки

MongoDB\Driver\Exception\InvalidArgumentException при неверных аргументах, пропусках ключей, неподходящем типе компоненты или выходе Int8/битов за пределы. В учебном контракте слишком большой для конечного Float32 double отклоняется до фабрики; не полагайтесь на неё как на бизнес-валидатор.

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

С 2.2.0. Страница PHP.net описывает метод, но содержит неточности SUBTYPE_VECTOR и -127..128; реальные имена и signed-диапазон здесь сверены с class synopsis, BSON vector specification и расширением 2.5.5.

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

Перенести числовые характеристики

Два float превращаются в subtype 9; после чтения видно округление 0.1 и точное сохранение 1.5.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Передать комплектацию устройства

Десять bool/int-флагов становятся компактным payload с padding, а затем возвращаются в исходном порядке для подписанного экрана.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Float32 сужает точность PHP double. Int8 не масштабирует единицы, PackedBit не назначает смысл позициям. Не выдавайте compact payload за подключённую нейросеть или готовый Atlas Vector Search. Упаковка сохраняет данные, а модель и способ сравнения задаются отдельным проектом.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::getDataПрочитать исходные bytes для файла, проверки целостности или просмотра формата.

mongodb 1.0.0; версии расширений — в карточке · mongodb

final public MongoDB\BSON\Binary::getData(): string

Прочитать исходные bytes для файла, проверки целостности или просмотра формата.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::getData(): string

Параметров у этого метода нет.

Что получит вызывающий код

PHP string с исходными байтами Binary, включая NUL и любые не-текстовые значения. Это не hex, не base64 и не автоматически отформатированный UUID. Для вектора возвращается весь payload, включая два байта metadata.

Ошибки

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

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

С 1.0.0. Алиас __toString доступен с 1.2.0; оба читают те же bytes. BinaryInterface задаёт соответствующий контракт с 1.3.0.

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

Проверить неизменность файла

hash("sha256", $read->getData()) сравнивается с исходным файлом. NUL и FF участвуют в проверке, а не исчезают при преобразовании.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Понять компактный формат поправок

bin2hex и strlen показывают 030080007f и пять байтов payload: metadata плюс три компоненты, без выдуманной оценки полной памяти базы.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Не вызывайте strlen($binary->getData()) как «размер документа в базе»: это только payload. Для текста интерфейса используйте hex/base64 с подписью либо разбор корректного формата. Безопасное экранирование HTML не делает исходный не-UTF-8 бинарный поток текстом.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::getTypeУзнать BSON-подтип перед выбором преобразования или совместимого фильтра.

mongodb 1.0.0; версии расширений — в карточке · mongodb

final public MongoDB\BSON\Binary::getType(): int

Узнать BSON-подтип перед выбором преобразования или совместимого фильтра.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::getType(): int

Параметров у этого метода нет.

Что получит вызывающий код

Целое значение подтипа 0..255. Оно соответствует группе формата: 0 generic, 4 UUID, 9 vector и другим константам Binary. У вектора это ещё не Float32/Int8/PackedBit: для них нужен getVectorType.

Ошибки

Документирован MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Метод не принимает параметры и не делает запрос в базу.

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

С 1.0.0. Сами новые подтипы появлялись позднее; например TYPE_VECTOR определён с 2.2.0. Наличие int 9 в старом документе не добавит в старое расширение новые методы.

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

Разобрать несрабатывающий UUID-поиск

Одинаковые bytes показывают подтипы 0/3/4 и выбирают разные документы. Читатель видит конкретную причину несовпадения.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Отделить бинарный вектор от его внутреннего формата

Проверка subtype 9 подтверждает общую BSON-категорию, затем getVectorType уточняет Float32 для правильной распаковки.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Подтип отражает сохранённую метку, но не подтверждает бизнес-схему, достоверность источника или право расшифровать значение. Не надо объявлять любой Binary UUID или vector только потому, что поле так назвали.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::getVectorTypeПрочитать формат компонент настоящего вектора перед использованием чисел.

mongodb 2.2.0 · mongodb

final public MongoDB\BSON\Binary::getVectorType(): MongoDB\BSON\VectorType

Прочитать формат компонент настоящего вектора перед использованием чисел.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::getVectorType(): MongoDB\BSON\VectorType

Параметров у этого метода нет.

Что получит вызывающий код

Один случай enum VectorType: Float32, Int8 или PackedBit. Сравнивайте enum с enum; для подписи используйте ->name. Этот enum не имеет backing value.

Ошибки

MongoDB\Driver\Exception\LogicException, если Binary не имеет векторный подтип 9. MongoDB\Driver\Exception\InvalidArgumentException документирован для разбора аргументов. Не предусмотрен мягкий ответ null для обычного файла.

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

С 2.2.0, вместе с VectorType и векторной фабрикой. Старое расширение, умеющее обычный Binary, не обязательно умеет этот метод.

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

Правильно прочитать поправки датчиков

Формат Int8 отделяется от подписанного в документе масштаба 0.1 °C; интерпретация чисел становится явной.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Проверить выходной контракт выбранных профилей

Экспорт допускает только Float32 и features-v2, затем отправляет format вместе с dimensions и числами; случайный другой формат не маскируется.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Тип компонент не равен модели. Два Float32-вектора одинаковой длины могут означать совершенно разные признаки; проверяйте dimensions и model_version отдельно. Номер 9 из getType не заменяет возвращаемый enum.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::jsonSerializeПолучить legacy Extended JSON представление бинарного значения без не-UTF-8 в строке JSON.

mongodb 1.2.0 · mongodb

final public MongoDB\BSON\Binary::jsonSerialize(): mixed

Получить legacy Extended JSON представление бинарного значения без не-UTF-8 в строке JSON.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::jsonSerialize(): mixed

Параметров у этого метода нет.

Что получит вызывающий код

Значение, пригодное для JSON-кодирования, а не готовая JSON-строка. json_encode(Binary) вызывает этот метод автоматически. В текущем драйвере Binary выдаёт legacy Extended JSON: $binary содержит base64, $type — hex-подтип. Эта форма отличается от Canonical и Relaxed Extended JSON современных BSON-документов.

Ошибки

Страница метода указывает MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Параметров нет. Ошибки кодирования json_encode принадлежат JSON API; JSON_THROW_ON_ERROR делает их явными. Не путайте это с отказом json_encode(getData()), где исходные bytes могут быть не UTF-8.

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

С 1.2.0: тогда Binary реализовал JsonSerializable. Наличие этого интерфейса не означает автоматический выбор современного Canonical Extended JSON.

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

Сделать совместимую диагностическую запись фрагмента

Для шести прочитанных байтов метод выдаёт QQD/Qg0K и подтип 00; это проверяемое представление для существующего legacy-потребителя.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Согласовать формат интеграции

На трёх байтах сравниваются автоматический json_encode(Binary) и современный Canonical; обратный путь восстанавливает и bytes, и subtype.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Для стандартизованного BSON-обмена явно используйте Document::toCanonicalExtendedJSON/toRelaxedExtendedJSON; не рассчитывайте, что json_encode сам сменит версию формата. Base64 сохраняет содержимое, но не делает его секретным и не заменяет контроль доступа к диагностике.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::toArrayРаспаковать бинарный вектор в числовой список для расчёта или понятного экрана.

mongodb 2.2.0 · mongodb

final public MongoDB\BSON\Binary::toArray(): array

Распаковать бинарный вектор в числовой список для расчёта или понятного экрана.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::toArray(): array

Параметров у этого метода нет.

Что получит вызывающий код

PHP-массив компонент для Binary subtype 9. Float32 возвращает float с точностью сохранённого формата; Int8 — int; PackedBit — int 0/1 без хвостового padding. Список может быть пустым, если был создан пустой вектор.

Ошибки

MongoDB\Driver\Exception\LogicException для Binary не-векторного подтипа; MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Обычный файл нельзя этим методом превратить в массив его байтов.

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

С 2.2.0. Правильное имя константы класса TYPE_VECTOR; старый текст с SUBTYPE_VECTOR не следует копировать в исполняемый PHP.

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

Построить экран комплектации

Десять восстановленных int 0/1 связываются с десятью подписями; шесть служебных padding-битов не превращаются в лишние признаки.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Подготовить ограниченный JSON для вычисляющего клиента

Только два выбранных профиля превращаются в values; заголовки общего списка вообще не требуют распаковки features.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Распаковка создаёт PHP-массив и расходует память. Выбирайте только нужные документы/поле, затем распаковывайте ограниченное число векторов. Метод не восстанавливает потерянную при Float32 точность и не знает смысл индекса или единицы.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\Binary::__toStringИспользовать бинарное значение там, где нужен исходный поток bytes.

mongodb 1.2.0 · mongodb

final public MongoDB\BSON\Binary::__toString(): string

Использовать бинарное значение там, где нужен исходный поток bytes.

Сигнатура и базовый контракт

final public MongoDB\BSON\Binary::__toString(): string

Параметров у этого метода нет.

Что получит вызывающий код

Исходные bytes Binary; алиас getData(). Вызывается явным (string)$binary и строковыми контекстами. Результат не является hex/base64 и не гарантирует UTF-8.

Ошибки

Отдельные исключения на странице метода не заявлены. Ошибки последующего потребителя — файла, JSON, HTML-вывода — обрабатываются по его собственному контракту. Не вызывайте строковый вывод произвольного Binary как готовую веб-страницу.

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

С 1.2.0. Binary явно реализует Stringable в PHP 8+ с mongodb 1.12.0. Удаление Serializable в 2.0.0 не отменяет __toString.

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

Сверить исходный файловый поток

Строковое приведение сравнивается побайтно с файлом и совпадает с getData, не убирая NUL.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Показать одинаковые bytes при разных метках

У всех трёх подтипов строковое представление одинаково, но Query различает значения: отдельно нужен getType.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Конкатенация с подписью может внедрить NUL/управляющие байты в журнал. Для видимого результата делайте bin2hex((string)$binary) или base64_encode с явным указанием кодировки. Приведение не включает subtype, поэтому одной строковой копии для полного BSON-контракта недостаточно.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\BinaryInterfaceОбъявить понятный тип параметра, возвращаемого значения или свойства для двоичных данных.

mongodb 1.3.0; типы обязательны с 2.0.0 · mongodb

interface MongoDB\BSON\BinaryInterface {
    public function getData(): string;
    public function getType(): int;
    public function __toString(): string;
}

Объявить понятный тип параметра, возвращаемого значения или свойства для двоичных данных.

Сигнатура и базовый контракт

interface MongoDB\BSON\BinaryInterface {
    public function getData(): string;
    public function getType(): int;
    public function __toString(): string;
}

Контракт используется через перечисленные методы; создание самого интерфейса не предусмотрено.

Что получит вызывающий код

Это интерфейс, а не объект для new. Binary его реализует. Пользовательская функция может потребовать BinaryInterface и опираться на три объявленных метода; контракт не включает getVectorType, toArray или jsonSerialize.

Ошибки

Интерфейс не реализует хранение и не задаёт отдельные исключения чтения. PHP проверяет совместимость сигнатур класса-реализации и аргумента типизированной функции. Одна пользовательская реализация этого интерфейса ещё не является обещанием автоматического BSON-кодирования как встроенного Binary.

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

С 1.3.0. С 1.15.0 на PHP 8+ возвращаемые типы были tentative: несовместимые реализации получали deprecation, временно подавляемый ReturnTypeWillChange. С 2.0.0 типы обязательны; атрибут не является заменой корректным сигнатурам современного кода.

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

Общая сводка двоичного вложения

bv126Summary(BinaryInterface $binary) вычисляет длину, subtype и hex для прочитанного файла, не завися от имени поля payload.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Та же диагностическая граница для вектора

Вектор — тоже BinaryInterface; helper сообщает 14 байтов payload. Векторная распаковка остаётся отдельным действием Binary, не приписанным интерфейсу.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Используйте интерфейс, когда задаче достаточно bytes и subtype. Если функция должна распаковать вектор, ей нужен дополнительный конкретный API Binary и проверка формата. Интерфейс описывает возможности объекта, а не HTML-панель и не сетевой протокол.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\BinaryInterface::getDataЗафиксировать в типизированном помощнике контракт получения исходных bytes.

mongodb 1.3.0; типы обязательны с 2.0.0 · mongodb

abstract public MongoDB\BSON\BinaryInterface::getData(): string

Зафиксировать в типизированном помощнике контракт получения исходных bytes.

Сигнатура и базовый контракт

abstract public MongoDB\BSON\BinaryInterface::getData(): string

Параметров у этого метода нет.

Что получит вызывающий код

Строка bytes, которую реализация считает своими двоичными данными. У встроенного Binary это исходный payload. Метод не принимает параметры; текстовая кодировка не обещана.

Ошибки

Страница интерфейса не определяет отдельные ошибки. Конкретная реализация определяет свои отказы; PHP требует совместимый string-результат. Преобразование полученных bytes в JSON/текст — отдельная операция.

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

С 1.3.0. Return type string был tentative на PHP 8+ с 1.15.0, а с 2.0.0 обязателен. Исторический ReturnTypeWillChange не заменяет тип в актуальном расширении.

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

Посчитать настоящий размер вложения

bv126Summary принимает интерфейс и использует strlen(getData()) для шести байтов файла; функция не знает его кодировку.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Оценить именно payload компактных поправок

Та же функция получает пять байтов metadata+компоненты, не выдавая эту цифру за размер MongoDB-документа или RAM.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Длина bytes не является размером всех полей документа. Не обещайте UTF-8 из-за типа string. Если нужно сохранить подтип при переносе, вызывайте ещё getType.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\BinaryInterface::getTypeСохранить метку двоичного формата в общей функции, не теряя её при чтении bytes.

mongodb 1.3.0; типы обязательны с 2.0.0 · mongodb

abstract public MongoDB\BSON\BinaryInterface::getType(): int

Сохранить метку двоичного формата в общей функции, не теряя её при чтении bytes.

Сигнатура и базовый контракт

abstract public MongoDB\BSON\BinaryInterface::getType(): int

Параметров у этого метода нет.

Что получит вызывающий код

Целое с подтипом значения. У MongoDB\BSON\Binary это unsigned-байт 0..255, возвращаемый как PHP int. Интерфейс задаёт сигнатуру, а конкретные правила значений предоставляет реализация.

Ошибки

Отдельных исключений интерфейс не перечисляет. PHP проверяет совместимость int-результата; не превращайте произвольную пользовательскую реализацию в источник доверенной метки без собственного контракта.

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

С 1.3.0. Tentative int с 1.15.0 на PHP 8+ стал обязательным в 2.0.0. Современная реализация должна объявить : int.

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

Разделить несовместимые идентификаторы

Общая сводка показывает 0, 3 и 4 рядом с одинаковым hex; это помогает диагностировать пустой результат фильтра.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Показать BSON-категорию битового профиля

Сводка показывает subtype 9, а специализированный Binary отдельно подтверждает PackedBit и даёт десять признаков.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Подтип 9 сообщает только «vector», не конкретный VectorType. Интерфейс не содержит getVectorType. Для корректной миграции UUID одного int 3 или 4 недостаточно: нужен известный порядок исходных байтов.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\BinaryInterface::__toStringОписать строковое приведение как чтение bytes, а не как готовое оформление для пользователя.

mongodb 1.3.0; типы обязательны с 2.0.0 · mongodb

abstract public MongoDB\BSON\BinaryInterface::__toString(): string

Описать строковое приведение как чтение bytes, а не как готовое оформление для пользователя.

Сигнатура и базовый контракт

abstract public MongoDB\BSON\BinaryInterface::__toString(): string

Параметров у этого метода нет.

Что получит вызывающий код

Двоичные данные объекта, по смыслу тот же результат, что getData(). Встроенный Binary позволяет получить их через (string)$binary. Подтип в эту строку не включён.

Ошибки

Интерфейс не задаёт отдельного списка исключений. Реализация обязана соблюдать string return type; ошибки вывода/кодировки обрабатываются потребителем. Интерфейс сам не создаётся и не вызывает MongoDB.

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

С 1.3.0. Как у других методов интерфейса: tentative string с 1.15.0, обязательный string с 2.0.0.

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

Безопасно показать содержимое вложения

В bv126Summary приведение немедленно передаётся в bin2hex, поэтому таблица содержит 4100ff420d0a вместо управляющих байтов.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Сравнить содержимое без смешения типов

Побайтное сравнение подтверждает одинаковую строковую часть всех трёх Binary, но таблица сохраняет и подтип: разница запросов остаётся объяснимой.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Человекочитаемую подпись делает вызывающий код, например bin2hex. Не стройте журнал конкатенацией непроверенного бинарного содержимого: в нём могут быть управляющие символы. Для восстановления полной пары переносите subtype отдельно.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

MongoDB\BSON\VectorTypeЯвно выбрать формат компонент вектора и прочитать тот же формат после MongoDB.

mongodb 2.2.0 · mongodb

enum MongoDB\BSON\VectorType {
    case Float32;
    case Int8;
    case PackedBit;
}

Явно выбрать формат компонент вектора и прочитать тот же формат после MongoDB.

Сигнатура и базовый контракт

enum MongoDB\BSON\VectorType {
    case Float32;
    case Int8;
    case PackedBit;
}
Вход / вариантЗначение и ограничение
Float32Каждая компонента — 32-битное число с плавающей точкой. Для PHP fromVector передавайте float.
Int8Знаковое восьмибитное целое -128..127; для PHP fromVector передавайте int.
PackedBitОдин бит на компоненту. PHP fromVector принимает bool либо int 0/1; toArray возвращает int 0/1.

Что получит вызывающий код

Случаи unit enum используются аргументом fromVector и возвращаются getVectorType. ->name даёт название. Здесь нет int/string backing type, поэтому ->value не предусмотрено; двоичные коды формата не являются backing values enum.

Ошибки

Enum не предоставляет отдельной операции, которая могла бы вернуть ошибку. Его значения передаются в методы с собственными ограничениями. Неподходящая компонента вызывает ошибку fromVector; неверный subtype — ошибку getVectorType/toArray.

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

С mongodb 2.2.0. Формат хранения vector subtype 9 не означает, что сервер выполняет векторный поиск; возможности поиска и индексов имеют отдельные требования.

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

Компактные физические поправки

Int8 выбран потому, что договорённый scale 0.1 °C укладывает исходные целые в signed-диапазон, а не потому, что любые числа можно молча обрезать.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Флаги комплектации

PackedBit выбирается для настоящих двоичных признаков; порядок десяти labels и schema_version остаются обязанностью приложения.

К исходным данным, короткому вызову, полной программе и результату · Открыть результат реального выполнения

Границы и следующий шаг

Выбор формата — часть схемы данных. Он не задаёт размерность, единицы, версию модели, допустимые NaN/Infinity или способ сравнения. Эти требования нужно хранить и проверять отдельно. На нашей странице Float32 для денег не рекомендуется из-за потери точности.

Связанные объяснения: ObjectId, даты и Decimal128; Document и типы Extended JSON; другой специальный BSON-тип: Regex и запросы.

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

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

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

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

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