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

Дерево руководства
Глава 151 · После массивов PHP, первого каталога MongoDB и типов BSON
MongoDB: BSON-массивы, строки корзины и последовательный обход
PackedArray от первого списка до вложенных документов, неизменяемой правки, пропусков ключей, точного JSON-обмена и реальной сохранённой корзины; полный справочник BSON Iterator.
Список, документ и бинарное представление: сначала различим задачи
У заказа несколько позиций, у товара несколько вариантов, у службы доставки несколько этапов. Во всех этих случаях важен порядок значений. Здесь мы построим понятный список, научимся различать номер места и постоянный ID, прочитаем вложенные строки корзины и сохраним одну корзину в MongoDB.
Начните с обычных массивов PHP, вложенных массивов и перебора и документа и коллекции MongoDB. PHP array — универсальный контейнер: он может быть списком или словарём. BSON различает массив и документ. PackedArray — неизменяемое представление BSON-массива в расширении PHP. Оно нужно, когда вы читаете raw BSON или хотите явно управлять его формой и типами. Для обычной работы можно использовать PHP-массивы с настроенной картой типов; PackedArray не обязателен в каждом проекте.
| Структура | Как выбираем значение | Пример |
|---|---|---|
| PHP-список | Целая позиция с 0 без пропусков | ["CUP", "LAMP"] |
| BSON-массив / PackedArray | get(0) | Первая строка корзины |
| BSON-документ / Document | get("sku") | Поле артикула внутри строки |
| Коллекция MongoDB | Серверный запрос по фильтру | Найти заказ 901 |
- Место 0: документ CUP, количество 2
- Место 1: документ LAMP, количество 1
- Номер места выбирает строку, имя поля выбирает значение
- Удаление строки меняет порядок мест, но постоянный ID товара сохраняется в поле
Аналогия с органайзером описывает доступ к данным, а не устройство памяти PHP. PackedArray не разрешает переставлять содержимое на месте: сначала создают редактируемую PHP-копию, затем новый контейнер. BSON — бинарный формат с типами; JSON — текстовый формат обмена. Создание любого из этих представлений само по себе не записывает данные на сервер.
$items = ['CUP', 'LAMP'];
$packed = MongoDB\BSON\PackedArray::fromPHP($items);
echo $packed->get(0); // CUP$items — имя переменной, = сохраняет значение, квадратные скобки создают PHP-список. Полное имя класса указывает на расширение mongodb; :: вызывает фабрику класса, -> вызывает метод готового объекта. Ноль — индекс первой позиции. Это минимальное действие не требует функции пользователя, JSON или подключения к базе. Каждый следующий полный пример ниже добавляет ровно свою практическую задачу.
Подготовить расширение; сервер нужен только для сохранения корзины
Нужны PHP 8.4+ CLI и ext-mongodb 2.5+. Шесть первых программ выполняют только локальное преобразование BSON; им не нужен запущенный сервер. Последняя программа действительно работает с MongoDB 8.0 на отдельном локальном порту 27075. Composer не нужен. В README каждого ZIP есть установка расширения, команды mongod, переменные окружения и запуск.
php --ri mongodb
php example.phpДля последнего сценария после подготовки отдельного сервера:
$env:PHPMAN_MONGODB_URI='mongodb://127.0.0.1:27075/?directConnection=true&retryWrites=false'
$env:PHPMAN_MONGODB_DATABASE='php_manual_lab'
php example.phpНомер позиции, пустое значение и отсутствующая позиция
В форме комплектации есть три места: CUP, ещё не выбранный товар и LAMP. Нужно показать пустое место, не перепутав его с четвёртым местом, которого вообще нет. Результат — таблица позиций, где NULL и «нет позиции» различаются.
Откуда берутся данные
Обычный PHP-список ["CUP", null, "LAMP"]. Ключи 0, 1, 2 появляются автоматически. Номер позиции начинается с нуля; это не ID товара. null здесь означает «место предусмотрено, выбор пока не сделан».
- PHP: 0 → CUP, 1 → null, 2 → LAMP
- fromPHP создаёт неизменяемый BSON-массив
- has(1) находит место; get(1) возвращает null
- has(3) возвращает false: get(3) уже вызвал бы исключение
- HTML показывает отдельно наличие и значение
Самая короткая полезная операция
$slots = MongoDB\BSON\PackedArray::fromPHP(['CUP', null, 'LAMP']);
echo $slots->get(0); // CUP
var_dump($slots->has(1)); // true: позиция есть, значение null.Что получится
| Индекс | Позиция существует | Значение | offsetExists |
|---|---|---|---|
| 0 | да | CUP | да |
| 1 | да | NULL | да |
| 2 | да | LAMP | да |
| 3 | нет | нет позиции | нет |
Как это работает
PackedArray::fromPHP — статический фабричный метод: знак :: выбирает метод класса, аргумент в скобках содержит исходный список, результат присваивается $slots. get(0) читает значение первого места, has(0) отвечает только на вопрос о наличии. Через offsetGet(0) или $slots[0] читается то же значение. offsetExists(1) возвращает true даже для хранимого null: это проверка существования. Сигнатура offsetExists принимает mixed, но реализация расширения 2.5.5 возвращает false для строки "0"; offsetGet поддерживает целый индекс и отвергает такую строку. Строгое разделение типов полезно при разборе номера из URL: сначала проверьте вход и получите int, затем обращайтесь к массиву.
Границы и ошибки
has не проверяет содержимое элемента: null, 0 и пустая строка могут присутствовать. get отсутствующего индекса бросает RuntimeException; эти ожидаемые случаи в полной программе перехвачены отдельно. Массив не становится коллекцией MongoDB: этот запуск локальный, сервер не используется. Если место обозначено артикулом, а не порядковым номером, нужен документ/словарь.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$slots = MongoDB\BSON\PackedArray::fromPHP(['CUP',null,'LAMP']);
$rows=[];
foreach ([0,1,2,3] as $index) {
$present=$slots->has($index);
$value=$present?$slots->get($index):'нет позиции';
$rows[]=[$index,$present?'да':'нет',$value,$slots->offsetExists($index)?'да':'нет'];
}
$missingRejected=false;
try { $slots->get(3); } catch (MongoDB\Driver\Exception\RuntimeException $e) { $missingRejected=true; }
$offsetRejected=false;
try { $slots->offsetGet('0'); } catch (MongoDB\Driver\Exception\RuntimeException $e) { $offsetRejected=true; }
$checks=['null_is_present'=>$slots->has(1) && $slots->offsetExists(1) && $slots->get(1)===null,
'first_value'=>$slots[0]==='CUP' && $slots->offsetGet(2)==='LAMP',
'missing_rejected'=>$missingRejected,'integer_offsets_only'=>!$slots->offsetExists('0') && $offsetRejected];
$details=['Входной список'=>['CUP',null,'LAMP'],'Проверка наличия и чтение разделены'=>true];
ma119Report('mongodb119-arrays-positions',['Индекс', 'Позиция существует', 'Значение', 'offsetExists'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-positions: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-positions: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Добавьте пустую строку четвёртым элементом. Решение: has(3) станет true, get(3) вернёт ""; проверка «пусто» зависит от правил формы, а не от has.
Исправить количество в копии, сохранив исходный список
Покупатель меняет CUP с двух штук на четыре. Старое состояние нужно сохранить для сравнения в форме. Получим две версии: исходные количества 2/1 и исправленные 4/1.
Откуда берутся данные
Список количеств [2, 1], где соответствие позициям CUP/LAMP задано исходной корзиной. В прикладной системе лучше хранить количество рядом с артикулом; следующий урок показывает такие документы.
- PackedArray хранит исходные количества 2 и 1
- Попытки offsetSet и offsetUnset завершаются LogicException
- toPHP даёт отдельный редактируемый массив
- PHP-копия получает 4 вместо 2
- fromPHP упаковывает новую версию; исходный BSON остался тем же
Самая короткая полезная операция
$quantities = MongoDB\BSON\PackedArray::fromPHP([2, 1]);
$copy = $quantities->toPHP();
$copy[0] = 4;
$updated = MongoDB\BSON\PackedArray::fromPHP($copy);
echo $quantities->get(0), ' → ', $updated->get(0); // 2 → 4Что получится
| Товар | Исходное количество | Количество в новой версии |
|---|---|---|
| CUP | 2 | 4 |
| LAMP | 1 | 1 |
Как это работает
PackedArray реализует ArrayAccess ради удобного чтения, но остаётся неизменяемым. Наличие квадратных скобок не означает разрешение записи. toPHP декодирует значения; в простом списке чисел получается обычный PHP array. Здесь явная карта типов делает root, document и array массивами PHP. Изменяется только $editable, затем fromPHP создаёт новый объект. Сравнение байтов до и после подтверждает неизменность исходного контейнера; разница хешей новой версии показывает изменение сериализованных данных, но не подтверждает сохранение в базе.
Границы и ошибки
У вложенных BSON-значений остаются собственные типы: Int64 и Decimal128 не обязаны превращаться в PHP int/float. Нельзя считать toPHP универсальным глубоким копированием произвольных пользовательских объектов. Для HTTP-формы дополнительно проверяют разрешённый диапазон количества. Преобразование всей большой коллекции в массив для редактирования не требуется: выборку ограничивают на сервере, а серверную правку делают $set/$inc по нужному документу.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$original=MongoDB\BSON\PackedArray::fromPHP([2,1]);
$beforeBytes=(string)$original;
$setRejected=false; $unsetRejected=false;
try { $original->offsetSet(0,4); } catch (MongoDB\Driver\Exception\LogicException $e) { $setRejected=true; }
try { $original->offsetUnset(1); } catch (MongoDB\Driver\Exception\LogicException $e) { $unsetRejected=true; }
$editable=$original->toPHP(['root'=>'array','document'=>'array','array'=>'array']);
$editable[0]=4;
$changed=MongoDB\BSON\PackedArray::fromPHP($editable);
$rows=[['CUP',$original->get(0),$changed->get(0)],['LAMP',$original->get(1),$changed->get(1)]];
$checks=['write_rejected'=>$setRejected,'unset_rejected'=>$unsetRejected,
'original_unchanged'=>(string)$original===$beforeBytes && $original->get(0)===2,
'new_value'=>$changed->get(0)===4 && $changed->get(1)===1,
'different_bson'=>(string)$changed!==$beforeBytes];
$details=['Действие'=>'Создан новый PackedArray; запроса update в базу нет','Редактируемая PHP-копия'=>$editable,
'SHA256 исходного BSON'=>hash('sha256',$beforeBytes),'SHA256 нового BSON'=>hash('sha256',(string)$changed)];
ma119Report('mongodb119-arrays-copy-edit',['Товар', 'Исходное количество', 'Количество в новой версии'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-copy-edit: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-copy-edit: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Увеличьте количество LAMP до 2 в копии. Решение: $editable[1] = 2 перед fromPHP; оригинал всё ещё возвращает 1 для позиции 1.
Пройти этапы отправки и начать обход заново
Службе отправки нужно показать очередность упаковки, печати этикетки и передачи заказа. Покажем простой foreach и ручное перемещение указателя, затем заново откроем первый шаг.
Откуда берутся данные
Локальный список ["pack", "label", "ship"]. Это названия этапов, а не реальные вызовы платёжной или транспортной службы. Повторное чтение списка безопасно; повторная отправка запроса в службу имела бы другие последствия.
- rewind ставит указатель на 0: pack
- valid разрешает чтение текущей позиции
- key даёт номер, current — название этапа
- next переводит указатель на 1, затем на 2
- После конца valid=false; rewind снова открывает 0
Самая короткая полезная операция
$stages = MongoDB\BSON\PackedArray::fromPHP(['pack', 'label', 'ship']);
foreach ($stages as $index => $stage) {
echo $index, ': ', $stage, "\n";
} // 0: pack, затем 1: label, затем 2: shipЧто получится
| Номер шага | Этап отправки |
|---|---|
| 0 | pack |
| 1 | label |
| 2 | ship |
Как это работает
foreach автоматически управляет итератором. Ручной вариант полезен, когда шаг нужно прочитать, решить, можно ли двигаться дальше, и только затем вызвать next. getIterator создаёт MongoDB\BSON\Iterator; напрямую new Iterator использовать нельзя. В цикле while условие valid проверяется до current/key. Когда элементы закончились, current и key бросают LogicException. В пустом списке valid уже false после rewind. Новый getIterator даёт отдельный объект обхода; rewind существующего сбрасывает его положение.
Границы и ошибки
BSON\Iterator обходит уже имеющееся BSON-значение в PHP. Это не MongoDB\Driver\Cursor, который выдаёт результат серверного запроса, и не курсор пагинации. next/rewind возвращают void: значение читают отдельным current. Не вызывайте current «на всякий случай» после конца. Повторный foreach/rewind повторяет чтение; если в теле стоят внешние побочные эффекты, их защиту от повторов проектируют отдельно.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$stages=MongoDB\BSON\PackedArray::fromPHP(['pack','label','ship']);
$foreachRows=[];
foreach ($stages as $index=>$stage) { $foreachRows[]=[$index,$stage]; }
$iterator=$stages->getIterator();
$iterator->rewind(); $rows=[];
while ($iterator->valid()) {
$rows[]=[$iterator->key(),$iterator->current()];
$iterator->next();
}
$ended=!$iterator->valid();
$invalidCurrent=false; $invalidKey=false;
try { $iterator->current(); } catch (MongoDB\Driver\Exception\LogicException $e) { $invalidCurrent=true; }
try { $iterator->key(); } catch (MongoDB\Driver\Exception\LogicException $e) { $invalidKey=true; }
$iterator->rewind();
$restart=[$iterator->key(),$iterator->current()];
$empty=MongoDB\BSON\PackedArray::fromPHP([])->getIterator(); $empty->rewind();
$checks=['same_order'=>$rows===$foreachRows && $rows===[[0,'pack'],[1,'label'],[2,'ship']],
'end_detected'=>$ended,'invalid_read_rejected'=>$invalidCurrent && $invalidKey,
'rewind_restarts'=>$restart===[0,'pack'],'empty_is_invalid'=>!$empty->valid()];
$details=['После rewind снова первая позиция'=>$restart,'Пустая очередь имеет valid=false'=>!$empty->valid(),
'Важно'=>'Обход только читает названия этапов; отправка заказа и побочные эффекты не выполняются'];
ma119Report('mongodb119-arrays-batch-iterator',['Номер шага', 'Этап отправки'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-batch-iterator: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-batch-iterator: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Перед ship остановите ручной обход, затем продолжите с того же итератора. Решение: остановиться, когда current() === "ship", не вызывая next; следующий участок программы продолжит с этой же позиции.
Список строк корзины: документ внутри массива
Одного артикула мало: у каждой строки корзины есть количество и выбранные опции. Нужно вывести две строки, не превращая вложенные значения в непрозрачную JSON-строку.
Откуда берутся данные
Верхний уровень — список строк. Каждая строка — документ с полями sku, quantity, options. У CUP две штуки и опции red/gift, у LAMP одна штука и пустой список опций.
- PackedArray: позиции 0 и 1
- Позиция 0 → Document {sku:CUP, quantity:2, options:[red,gift]}
- get("options") → вложенный PackedArray
- Итератор списка выдаёт Document каждой строки
- Явная карта toPHP делает редактируемую структуру PHP
Самая короткая полезная операция
$cart = MongoDB\BSON\PackedArray::fromPHP([
['sku' => 'CUP', 'quantity' => 2],
['sku' => 'LAMP', 'quantity' => 1],
]);
echo $cart->get(0)->get('sku'); // CUP: позиция 0 → документ → поле skuЧто получится
| Индекс строки | Артикул | Количество | Опции |
|---|---|---|---|
| 0 | CUP | 2 | red, gift |
| 1 | LAMP | 1 |
Как это работает
BSON-массив отвечает на вопрос «какое место?», BSON-документ — «какое поле?». Поэтому get(0)->get("sku") сначала выбирает позицию, затем именованное поле. Значение options снова является PackedArray; его можно обходить foreach независимо. По умолчанию toPHP превращает вложенный документ в stdClass, а BSON-массив — в PHP array. В полной программе document => array выбран явно, поэтому правка записывается как $copy[0]["quantity"]. Конвертация fromJSON показана только после этой модели: текст JSON становится BSON-контейнером, не требуется гонять через JSON уже пригодный PHP-массив. Canonical/Relaxed строки здесь служат диагностике.
Границы и ошибки
Пустой список [] и пустой документ {} различаются по смыслу и BSON-типу. Не заменяйте оба без разбора пустым PHP-массивом. Для всех пользовательских записей проверяйте схему строки: наличие sku, тип quantity, допустимые опции. Экран не должен угадывать, что произвольный элемент является Document. В исходных данных этого урока форма каждой строки задана программой и проверяется.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$cart=MongoDB\BSON\PackedArray::fromPHP([
['sku'=>'CUP','quantity'=>2,'options'=>['red','gift']],
['sku'=>'LAMP','quantity'=>1,'options'=>[]],
]);
$iterator=$cart->getIterator(); $iterator->rewind(); $rows=[]; $nestedTypes=true;
while ($iterator->valid()) {
$line=$iterator->current(); $options=$line->get('options');
$nestedTypes=$nestedTypes && $line instanceof MongoDB\BSON\Document && $options instanceof MongoDB\BSON\PackedArray;
$rows[]=[$iterator->key(),$line->get('sku'),$line->get('quantity'),implode(', ',$options->toPHP())];
$iterator->next();
}
$ended=!$iterator->valid(); $iterator->rewind();
$copy=$cart->toPHP(['root'=>'array','document'=>'array','array'=>'array']);
$copy[0]['quantity']=3;
$edited=MongoDB\BSON\PackedArray::fromPHP($copy);
$imported=MongoDB\BSON\PackedArray::fromJSON('[{"sku":"CUP","quantity":2,"options":["red","gift"]}]');
$canonical=$imported->toCanonicalExtendedJSON(); $relaxed=$imported->toRelaxedExtendedJSON();
$checks=['nested_types'=>$nestedTypes,'rows_match'=>$rows===[[0,'CUP',2,'red, gift'],[1,'LAMP',1,'']],
'rewind_keeps_first'=>$ended && $iterator->key()===0 && $iterator->current()->get('sku')==='CUP',
'copy_does_not_edit_source'=>$cart->get(0)->get('quantity')===2 && $edited->get(0)->get('quantity')===3,
'json_import'=>$imported->get(0)->get('sku')==='CUP' && MongoDB\BSON\PackedArray::fromJSON($canonical)->get(0)->get('quantity')===2];
$details=['PHP-копия с явной картой типов'=>$copy,'Canonical JSON строки'=>$canonical,'Relaxed JSON строки'=>$relaxed];
ma119Report('mongodb119-arrays-nested-lines',['Индекс строки', 'Артикул', 'Количество', 'Опции'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-nested-lines: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-nested-lines: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Добавьте третью строку с одной опцией blue. Решение: добавьте документ с sku/quantity/options в исходный PHP-список; внешний цикл даст новую строку, внутренний список options сохранит независимые индексы.
Практический вопрос: How to write empty associative array ({}) to MongoDB from PHP. Пустой документ и пустой список имеют разный прикладной смысл. В нашем примере options остаётся списком, а именованные поля — документом; ответы со старым Mongo API не считаются текущим техническим контрактом. Исторический вопрос используется для выбора задачи; контракт текущего драйвера сверён по PHP.net и исходникам расширения. Примеры этой главы самостоятельные.
После удаления строки восстановить список, сохранив ID товара
Из выбранных товаров удалили BAG. PHP сохранил ключи 0 и 2; интеграция ждёт список без пропусков. Получим позиции 0/1 и сохраним постоянные ID 101/309.
Откуда берутся данные
Три документа товара с полями id и sku. unset($selected[1]) удаляет вторую запись, но не перенумеровывает PHP-массив. Отдельный словарь 101 => CUP, 309 => LAMP показывает случай, где ключи имеют самостоятельный смысл.
- Исходные позиции 0/1/2 → удаление 1
- Остались ключи 0/2: fromPHP отказывает
- array_values сохраняет порядок значений и даёт 0/1
- ID остаются полями 101/309 внутри документов
- Если ID являются ключами словаря, сохраняем Document
Самая короткая полезная операция
$selected = ['CUP', 'BAG', 'LAMP'];
unset($selected[1]); // Ключи 0 и 2: это уже не список.
$list = array_values($selected); // Ключи 0 и 1.
$packed = MongoDB\BSON\PackedArray::fromPHP($list);
echo $packed->get(1); // LAMPЧто получится
| Новая позиция | Постоянный ID товара | Артикул |
|---|---|---|
| 0 | 101 | CUP |
| 1 | 309 | LAMP |
Как это работает
PackedArray::fromPHP принимает только список: пустой массив или последовательные целые ключи с нуля. Он не исправляет ключи автоматически. array_values — осознанное решение, когда ключ означает только позицию. Для ссылок на конкретный товар используется id внутри записи; позиция 1 после удаления не равна ID 1. Если же число в ключе является бизнес-идентификатором, Document сохраняет его как имя поля. Полная программа также показывает, что нормализация списка не отменяет неизменяемость PackedArray: запись и unset через [] по-прежнему запрещены.
Границы и ошибки
Удаление и перестановка меняют позиции, поэтому долговременные ссылки на элементы нельзя строить только по индексу. array_filter также сохраняет ключи; после фильтрации проверьте, по-прежнему ли нужен список. Не превращайте словарь в list ради подавления исключения: это потеря соответствия ключей и значений. BSON-массив не является универсальной заменой любому PHP array.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$selected=[['id'=>101,'sku'=>'CUP'],['id'=>205,'sku'=>'BAG'],['id'=>309,'sku'=>'LAMP']];
unset($selected[1]);
$gapRejected=false;
try { MongoDB\BSON\PackedArray::fromPHP($selected); }
catch (MongoDB\Driver\Exception\InvalidArgumentException $e) { $gapRejected=true; }
$list=array_values($selected);
$packed=MongoDB\BSON\PackedArray::fromPHP($list);
$setRejected=false; $unsetRejected=false;
try { $packed[0]=['id'=>999,'sku'=>'WRONG']; } catch (MongoDB\Driver\Exception\LogicException $e) { $setRejected=true; }
try { unset($packed[1]); } catch (MongoDB\Driver\Exception\LogicException $e) { $unsetRejected=true; }
$rows=[];
foreach ($packed as $position=>$line) { $rows[]=[$position,$line->get('id'),$line->get('sku')]; }
$map=['101'=>'CUP','309'=>'LAMP'];
$named=MongoDB\BSON\Document::fromPHP($map);
$checks=['gap_rejected'=>$gapRejected,'continuous_positions'=>array_keys($list)===[0,1],
'ids_preserved'=>$rows===[[0,101,'CUP'],[1,309,'LAMP']],
'packed_still_immutable'=>$setRejected && $unsetRejected && $packed->get(0)->get('id')===101,
'semantic_keys_stay_document'=>$named->get('309')==='LAMP'];
$details=['Ключи после unset'=>array_keys($selected),'Ключи после array_values'=>array_keys($list),
'Если ключ обозначает ID, это словарь'=>['101'=>'CUP','309'=>'LAMP'],'PHP-копия списка'=>$packed->toPHP(['document'=>'array'])];
ma119Report('mongodb119-arrays-reindex-selection',['Новая позиция', 'Постоянный ID товара', 'Артикул'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-reindex-selection: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-reindex-selection: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Удалите первый, а не второй товар. Решение: оставшиеся ключи 1/2 станут 0/1 после array_values, но поля id останутся 205/309. Запишите ожидаемые строки до запуска.
Практический вопрос: Mongodb 2.6.0-rc2 and PHP 1.4.5: find _id $in. После удаления элементов ключи PHP перестают образовывать список, что меняет BSON-форму. В уроке показаны осознанная перенумерация и сохранение постоянных ID; код исторического драйвера не переносится. Исторический вопрос используется для выбора задачи; контракт текущего драйвера сверён по PHP.net и исходникам расширения. Примеры этой главы самостоятельные.
Передать список с точными BSON-типами без подмены JSON
Сервис передаёт список счётчиков и денежных значений. Число 42 требуется сохранить именно как BSON int64, а стоимость 19.90 — как Decimal128. Сравним точный обмен и удобный для чтения JSON на тех же данных.
Откуда берутся данные
Extended JSON-массив содержит {$numberLong:"42"} и {$numberDecimal:"19.90"}. Обёртки — обозначения BSON-типов, а не обычные поля товара. В уже изученном разделе BSON-значений разобраны сами Int64 и Decimal128.
- fromJSON восстанавливает типы Int64 и Decimal128
- Canonical оставляет явные обозначения типов
- Повторный fromJSON Canonical сохраняет BSON-байты
- Relaxed пишет малое целое 42 без указания int64
- Обратное чтение Relaxed даёт PHP int / BSON int32
Самая короткая полезная операция
$values = MongoDB\BSON\PackedArray::fromJSON('[{"$numberLong":"42"}]');
$json = $values->toCanonicalExtendedJSON();
$restored = MongoDB\BSON\PackedArray::fromJSON($json);
echo get_debug_type($restored->get(0)); // MongoDB\BSON\Int64Что получится
| Путь преобразования | Значение счётчика | PHP-тип счётчика | Decimal128 |
|---|---|---|---|
| Исходный BSON | 42 | MongoDB\BSON\Int64 | 19.90 |
| Canonical → BSON | 42 | MongoDB\BSON\Int64 | 19.90 |
| Relaxed → BSON | 42 | int | 19.90 |
Как это работает
Canonical Extended JSON выбирают, когда нужно различать типы при обратном преобразовании. Relaxed удобнее для чтения, но не гарантирует ту же числовую разновидность: в нашем конкретном примере значение 42 сохраняется, а int64 превращается в int32. Decimal128 продолжает иметь собственную обёртку. __toString возвращает сырые BSON-байты, которые могут содержать нули и не являются печатным JSON. У PackedArray нет публичного fromBSON: для бинарного обмена список помещён в поле items документа; Document::fromBSON восстанавливает этот документ и исходный вложенный массив. Хеш/размер в отчёте помогают сравнить байты без вывода бинарного мусора в HTML.
Границы и ошибки
Canonical JSON не заменяет проверку схемы и доверия к источнику. В программе отклоняются ошибочный JSON и объект с именованным полем sku. Есть тонкость драйвера 2.5.5: объект JSON с ключами "0", "1", … может пройти fromJSON, поскольку проверяется последовательность полученных BSON-ключей, а не исходный символ [ или {. Если внешний контракт требует именно JSON-массив, его форму проверяют отдельно до преобразования. Обычные json_decode/json_encode не знают BSON-типов автоматически. Для JavaScript также существенна точность больших чисел; публичное API должно явно оговаривать строковое представление идентификаторов и денежных значений. Не используйте serialize/unserialize недоверенных объектов как формат обмена.
Отдельные типы и их прикладной смысл: ObjectId, время, Decimal128 и точный обмен.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
$values=MongoDB\BSON\PackedArray::fromJSON('[{"$numberLong":"42"},{"$numberDecimal":"19.90"}]');
$canonical=$values->toCanonicalExtendedJSON(); $relaxed=$values->toRelaxedExtendedJSON();
$exact=MongoDB\BSON\PackedArray::fromJSON($canonical);
$readable=MongoDB\BSON\PackedArray::fromJSON($relaxed);
$raw=(string)$values;
$envelope=MongoDB\BSON\Document::fromPHP(['items'=>$values]);
$restored=MongoDB\BSON\Document::fromBSON((string)$envelope)->get('items');
$invalidJson=false; $wrongRoot=false;
try { MongoDB\BSON\PackedArray::fromJSON('[1'); } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { $invalidJson=true; }
try { MongoDB\BSON\PackedArray::fromJSON('{"sku":"CUP"}'); } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { $wrongRoot=true; }
$rows=[['Исходный BSON',(string)$values->get(0),get_debug_type($values->get(0)),(string)$values->get(1)],
['Canonical → BSON',(string)$exact->get(0),get_debug_type($exact->get(0)),(string)$exact->get(1)],
['Relaxed → BSON',(string)$readable->get(0),get_debug_type($readable->get(0)),(string)$readable->get(1)]];
$checks=['canonical_type_kept'=>$exact->get(0) instanceof MongoDB\BSON\Int64 && (string)$exact===$raw,
'relaxed_changes_integer_type'=>is_int($readable->get(0)) && $readable->get(0)===42,
'decimal_kept'=>(string)$readable->get(1)==='19.90',
'binary_envelope_roundtrip'=>$restored instanceof MongoDB\BSON\PackedArray && (string)$restored===$raw,
'bad_json_rejected'=>$invalidJson && $wrongRoot];
$details=['Canonical Extended JSON'=>$canonical,'Relaxed Extended JSON'=>$relaxed,
'BSON массива, байт'=>strlen($raw),'SHA256 сырого BSON'=>hash('sha256',$raw),
'Начало BSON в hex'=>bin2hex(substr($raw,0,12)),
'Почему envelope'=>'Для переносимого бинарного контейнера список помещён в поле items документа; конструктор PackedArray закрыт'];
ma119Report('mongodb119-arrays-typed-exchange',['Путь преобразования', 'Значение счётчика', 'PHP-тип счётчика', 'Decimal128'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-typed-exchange: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-typed-exchange: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Замените $numberLong:"42" на большое точное значение из контракта своего сервиса. Решение: сохраняйте Canonical или явную строку в публичном API; не делайте вывод о сохранении типа только из одинаково напечатанных цифр.
Практический вопрос: Force a numeral to be stored as NumberLong with PHP driver. Одинаково напечатанные цифры не доказывают сохранение BSON int64. Canonical восстанавливает Int64; малое число 42 после Relaxed показывает потерю разрядности типа без заимствования старого обходного решения. Исторический вопрос используется для выбора задачи; контракт текущего драйвера сверён по PHP.net и исходникам расширения. Примеры этой главы самостоятельные.
Сохранить корзину и прочитать только нужные поля
Нужно сохранить корзину заказа, а затем вывести только её позиции и сумму. Этот запуск действительно записывает два документа в MongoDB, выбирает один и возвращает таблицу CUP/LAMP на 1900 копеек.
Откуда берутся данные
Заказ 901 содержит два CUP по 500 копеек и один LAMP за 900. Заказ 902 пустой. В 901 дополнительно есть внутреннее примечание, которое экрану не нужно.
- fromPHP создаёт список позиций в памяти
- BulkWrite помещает список в поле positions документа 901
- executeBulkWrite отправляет документы в свою коллекцию
- Query фильтрует _id=901, projection оставляет positions, limit=1
- root => bson возвращает Document; get("positions") даёт PackedArray
- foreach строит таблицу; finally удаляет свою коллекцию
Самая короткая полезная операция
$positions = MongoDB\BSON\PackedArray::fromPHP([
['sku' => 'CUP', 'quantity' => 2],
]);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(['_id' => 901, 'positions' => $positions]);
$manager->executeBulkWrite($namespace, $bulk); // Здесь данные отправляются на сервер.Что получится
| Позиция | Артикул | Количество | Сумма строки, копейки |
|---|---|---|---|
| 0 | CUP | 2 | 1000 |
| 1 | LAMP | 1 | 900 |
Как это работает
Корневой записью MongoDB служит документ. Список позиций — его вложенное поле, поэтому PackedArray передаётся внутрь документа, а не вместо него. setTypeMap(["root"=>"bson"]) просит курсор вернуть необработанный BSON-документ. Дальнейшее чтение get возвращает вложенный PackedArray с собственными Document-строками. Фильтр, projection и limit ограничивают данные до попадания в PHP. Вычисление двух сумм строк здесь нужно для представления небольшой ограниченной корзины; это не выборка всех заказов с последующей фильтрацией в памяти.
Границы и ошибки
Проекция ограничивает возвращаемые поля, но не является системой прав доступа. В реальном сервисе запрос включает проверенный идентификатор пользователя/магазина и авторизацию заказа. Сохранение подтверждается WriteResult, тип и значения — отдельным реальным чтением; результат локального fromPHP ничего не говорит о базе. Это демонстрация обычной записи, без обещаний многодокументной транзакции. Изменение PHP-копии не меняет сохранённый заказ: для него нужен отдельный update.
Полная самостоятельная программа, helper и ZIP
<?php
declare(strict_types=1);
require __DIR__.'/ma119-helper.php';
$runtime = ma119Runtime();
[$manager,$database]=ma119Database();
$runtime['server']=ma119Command($manager,$database,['buildInfo'=>1])[0]['version']; $runtime['execution']='database';
$collection='mongodb119_arrays_'.bin2hex(random_bytes(8)); $namespace=$database.'.'.$collection; $owned=false;
try {
if (ma119Exists($manager,$database,$collection)) { throw new RuntimeException('Fixture already exists'); }
ma119Command($manager,$database,['create'=>$collection],true); $owned=true;
$lines=MongoDB\BSON\PackedArray::fromPHP([
['sku'=>'CUP','quantity'=>2,'price'=>500],['sku'=>'LAMP','quantity'=>1,'price'=>900],
]);
$bulk=new MongoDB\Driver\BulkWrite();
$bulk->insert(['_id'=>901,'status'=>'draft','positions'=>$lines,'internalNote'=>'Not for this screen']);
$bulk->insert(['_id'=>902,'status'=>'draft','positions'=>MongoDB\BSON\PackedArray::fromPHP([])]);
$written=$manager->executeBulkWrite($namespace,$bulk);
$cursor=$manager->executeQuery($namespace,new MongoDB\Driver\Query(['_id'=>901],
['projection'=>['_id'=>0,'positions'=>1],'limit'=>1,'maxTimeMS'=>1000]));
$cursor->setTypeMap(['root'=>'bson']);
$documents=$cursor->toArray(); $document=$documents[0]; $saved=$document->get('positions');
$rows=[]; $total=0;
foreach ($saved as $index=>$line) {
$sum=$line->get('quantity')*$line->get('price'); $total+=$sum;
$rows[]=[$index,$line->get('sku'),$line->get('quantity'),$sum];
}
$checks=['two_documents_inserted'=>$written->getInsertedCount()===2,
'bounded_result'=>count($documents)===1 && $document instanceof MongoDB\BSON\Document,
'only_screen_fields'=>!$document->has('_id') && !$document->has('internalNote') && $document->has('positions'),
'bson_array_restored'=>$saved instanceof MongoDB\BSON\PackedArray && $saved->has(0) && $saved->offsetExists(1) && !$saved->has(2),
'first_and_last'=>$saved[0]->get('sku')==='CUP' && $saved->offsetGet(1)->get('sku')==='LAMP',
'cart_total'=>$total===1900];
$details=['Сумма корзины, копейки'=>$total,'Поля выборки'=>['positions'],
'Список из базы в Canonical JSON'=>$saved->toCanonicalExtendedJSON(),
'Это отдельная запись'=>'Обычное создание PackedArray не обращается к MongoDB; здесь выполнен executeBulkWrite и затем executeQuery'];
} finally { if ($owned) { ma119Command($manager,$database,['drop'=>$collection],true); } }
$checks['owned_collection_removed']=!ma119Exists($manager,$database,$collection);
ma119Report('mongodb119-arrays-saved-cart',['Позиция', 'Артикул', 'Количество', 'Сумма строки, копейки'],$rows,$checks,$runtime,$details);
echo 'mongodb119-arrays-saved-cart: saved result.html and result.json
';
Ожидаемый результат
mongodb119-arrays-saved-cart: saved result.html and result.json
Запустите php example.php и откройте result.html. В архиве ma119-helper.php и полный README. Режим codec-only не обращается к серверу; saved-cart подтверждает реальную запись/чтение и удаление своей коллекции.
Посмотреть результат реального запуска · Скачать таблицу JSON
Попробуйте сами. Добавьте поле supplierCost в позицию и не показывайте его покупателю. Решение: определить нужные поля в серверной проекции и HTML; отдельно продумать права доступа. Не полагайтесь на скрытый столбец браузера как на защиту данных.
Все методы PackedArray и BSON Iterator: контракты и применения
14 методов PackedArray и 6 методов Iterator. У каждого разобраны параметры, результат, ошибки, версии и два применения в полных сценариях. Закрытые конструкторы тоже объяснены: их нельзя подменять выдуманным new.
| Метод | Практическое назначение |
|---|---|
| MongoDB\BSON\PackedArray::__construct | Понять, почему PackedArray создают фабрикой, а не new. |
| MongoDB\BSON\PackedArray::fromPHP | Создать BSON-массив из настоящего списка PHP. |
| MongoDB\BSON\PackedArray::fromJSON | Восстановить BSON-массив из JSON или Extended JSON. |
| MongoDB\BSON\PackedArray::get | Получить значение конкретной позиции. |
| MongoDB\BSON\PackedArray::has | Отделить наличие позиции от её значения. |
| MongoDB\BSON\PackedArray::offsetExists | Проверить наличие через интерфейс ArrayAccess. |
| MongoDB\BSON\PackedArray::offsetGet | Читать позицию через [] или явный offsetGet. |
| MongoDB\BSON\PackedArray::offsetSet | Разобрать запрет изменения PackedArray и правильную замену. |
| MongoDB\BSON\PackedArray::offsetUnset | Разобрать запрет удаления позиции из неизменяемого BSON. |
| MongoDB\BSON\PackedArray::toPHP | Получить удобную PHP-структуру для обработки или новой версии. |
| MongoDB\BSON\PackedArray::toCanonicalExtendedJSON | Получить текст для обмена с сохранением BSON-типов. |
| MongoDB\BSON\PackedArray::toRelaxedExtendedJSON | Сделать BSON-массив удобнее для чтения, учитывая потери разновидности типа. |
| MongoDB\BSON\PackedArray::__toString | Получить сырые BSON-байты для сравнения или контейнера обмена. |
| MongoDB\BSON\PackedArray::getIterator | Создать объект последовательного обхода BSON-массива. |
| MongoDB\BSON\Iterator::__construct | Получить BSON-итератор от контейнера, не создавая неинициализированный объект. |
| MongoDB\BSON\Iterator::current | Прочитать значение в текущем месте без продвижения. |
| MongoDB\BSON\Iterator::key | Узнать ключ текущего элемента, а не его значение. |
| MongoDB\BSON\Iterator::next | Перейти к следующему элементу после обработки текущего. |
| MongoDB\BSON\Iterator::rewind | Вернуться к первому элементу для нового прохода. |
| MongoDB\BSON\Iterator::valid | Проверить, разрешено ли сейчас читать current и key. |
Связать контейнер с реальным контрактом приложения
Выбирайте структуру по смыслу: порядок мест — список, имена/ID в ключах — документ, много самостоятельных записей — коллекция. Сначала ограничьте данные серверным запросом; затем обрабатывайте нужный контейнер в PHP. Для редактирования создайте новую версию, а сохранение в базу выполняйте явной командой.
Далее: BSON-документы с именованными полями, запросы и операции низкоуровневого драйвера, условная атомарная правка одного документа. Если нужны типизированные идентификаторы, даты и деньги, вернитесь к значениям BSON.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
MongoDB\BSON\PackedArray::__constructПонять, почему PackedArray создают фабрикой, а не new.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final private MongoDB\BSON\PackedArray::__construct()Понять, почему PackedArray создают фабрикой, а не new.
final private MongoDB\BSON\PackedArray::__construct()Параметры
Параметров нет.
Результат
У пользовательского кода нет доступного вызова. Объект возвращают fromPHP/fromJSON или получают при чтении вложенного BSON-массива.
Ошибки и ограничения
Прямой new MongoDB\BSON\PackedArray() запрещён закрытым конструктором; на уровне PHP это Error доступа, а не пустой контейнер.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Класс final и неизменяемый. С 1.17.0 реализует BSON\Type; с 1.17.0 его нельзя сериализовать там, где ожидается корневой BSON-документ (ранее массив превращался в документ). С 2.0.0 класс больше не реализует интерфейс Serializable. Не путайте это с отдельным классом MongoDB\Model\BSONArray из Composer-библиотеки.
Упаковать места комплектации
$slots = MongoDB\BSON\PackedArray::fromPHP(['CUP', null, 'LAMP']);Фабрика создаёт контейнер с позициями 0/1/2, в том числе явно пустым местом.
Входные данные и полный рабочий сценарий · Результат запуска
Принять типизированный список интеграции
$values = MongoDB\BSON\PackedArray::fromJSON('[{"$numberLong":"42"}]');Второй путь создания — фабрика JSON; счётчик получает точный BSON int64.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::fromPHPСоздать BSON-массив из настоящего списка PHP.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public static MongoDB\BSON\PackedArray::fromPHP(array $value): MongoDB\BSON\PackedArrayСоздать BSON-массив из настоящего списка PHP.
final public static MongoDB\BSON\PackedArray::fromPHP(array $value): MongoDB\BSON\PackedArrayПараметры
| Параметр | Смысл |
|---|---|
| $value: array | Пустой список либо последовательные целочисленные ключи 0, 1, 2, … без пропусков; вложенные значения сериализуются в соответствующие BSON-типы. |
Результат
Новый PackedArray; исходный PHP-массив не становится серверной коллекцией.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. Если array не является списком, выбрасывается InvalidArgumentException.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Не исправляет ключи сам. Если ключи обозначают идентификаторы, выберите Document или перенесите ID в поля записей до формирования списка.
Упаковать места комплектации
$slots = MongoDB\BSON\PackedArray::fromPHP(['CUP', null, 'LAMP']);Фабрика создаёт контейнер с позициями 0/1/2, в том числе явно пустым местом.
Входные данные и полный рабочий сценарий · Результат запуска
Упаковать выбор после удаления товара
$packed = MongoDB\BSON\PackedArray::fromPHP(array_values($selected));После осознанного уплотнения позиции становятся 0/1, ID 101/309 остаются полями строк.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::fromJSONВосстановить BSON-массив из JSON или Extended JSON.
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+. · mongodb
final public static MongoDB\BSON\PackedArray::fromJSON(string $json): MongoDB\BSON\PackedArrayВосстановить BSON-массив из JSON или Extended JSON.
final public static MongoDB\BSON\PackedArray::fromJSON(string $json): MongoDB\BSON\PackedArrayПараметры
| Параметр | Смысл |
|---|---|
| $json: string | JSON-значение для преобразования в BSON-массив; в нашем контракте это текст списка. Extended JSON может содержать обёртки BSON-типов. |
Результат
Новый PackedArray с декодированными значениями.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. UnexpectedValueException означает, что текст нельзя преобразовать в BSON-массив: например, ошибка синтаксиса или BSON-ключи, не образующие список.
Версии
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+.
Не требуется промежуточный json_decode для самого BSON-преобразования. Корректный JSON ещё не гарантирует правильную схему заказа: диапазоны и обязательные поля проверяет приложение. В 2.5.5 объект JSON с последовательными числовыми ключами также может пройти преобразование; если ваш внешний контракт требует именно JSON-массив, проверяйте эту форму отдельно. Это уточнение сверено с реализацией драйвера.
Принять одну строку корзины
$imported = MongoDB\BSON\PackedArray::fromJSON('[{"sku":"CUP","quantity":2}]');Позиция 0 — Document с артикулом CUP и количеством 2; затем можно проверить поля.
Входные данные и полный рабочий сценарий · Результат запуска
Принять типизированный список интеграции
$values = MongoDB\BSON\PackedArray::fromJSON('[{"$numberLong":"42"}]');Второй путь создания — фабрика JSON; счётчик получает точный BSON int64.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::getПолучить значение конкретной позиции.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::get(int $key): mixedПолучить значение конкретной позиции.
final public MongoDB\BSON\PackedArray::get(int $key): mixedПараметры
| Параметр | Смысл |
|---|---|
| $key: int | Индекс элемента в массиве; в списке первая позиция 0. |
Результат
Значение позиции; сохранённый null возвращается как null. Вложенные BSON-документы/массивы доступны как Document/PackedArray. BSON int64 возвращается объектом MongoDB\BSON\Int64, в том числе на 64-битном PHP.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. Отсутствующий индекс вызывает MongoDB\Driver\Exception\RuntimeException; для проверки наличия есть has.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Различить пустое и отсутствующее место
if ($slots->has(1)) { $value = $slots->get(1); }Место 1 существует и содержит null; место 3 отсутствует. Таблица не теряет это различие.
Входные данные и полный рабочий сценарий · Результат запуска
Прочитать артикула ограниченной корзины
$firstSku = $saved->get(0)->get('sku');После запроса одного заказа первая строка даёт CUP; перед чтением полнота списка проверяется has.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::hasОтделить наличие позиции от её значения.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::has(int $index): boolОтделить наличие позиции от её значения.
final public MongoDB\BSON\PackedArray::has(int $index): boolПараметры
| Параметр | Смысл |
|---|---|
| $index: int | Искомая целочисленная позиция. |
Результат
true, если позиция существует; false, если нет. Значение null не делает существующую позицию отсутствующей.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Различить пустое и отсутствующее место
if ($slots->has(1)) { $value = $slots->get(1); }Место 1 существует и содержит null; место 3 отсутствует. Таблица не теряет это различие.
Входные данные и полный рабочий сценарий · Результат запуска
Проверить границы сохранённой корзины
$hasTwo = $saved->has(0) && $saved->has(1) && !$saved->has(2);У заказа две позиции, третьей нет. Это проверка структуры результата, а не бизнес-валидация SKU.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::offsetExistsПроверить наличие через интерфейс ArrayAccess.
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::offsetExists(mixed $key): boolПроверить наличие через интерфейс ArrayAccess.
final public MongoDB\BSON\PackedArray::offsetExists(mixed $key): boolПараметры
| Параметр | Смысл |
|---|---|
| $key: mixed | Номер позиции. В проверенной реализации 2.5.5 значения не-int возвращают false; строка "0" не равна индексу 0. |
Результат
true для существующей позиции, включая null; иначе false.
Ошибки и ограничения
Страница метода не перечисляет отдельные исключения для допустимого вызова. Для неверного количества аргументов действуют проверки PHP/расширения. Не переносите семантику isset обычного PHP-массива на этот метод.
Версии
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+.
ArrayAccess позволяет использовать isset($packed[$i]); выбор между наличием и проверкой содержимого должен быть явным. Для строго типизированного прямого вызова удобен has(int).
Не потерять пустое место
$exists = $slots->offsetExists(1); // true при nullФорма знает, что второе место предусмотрено.
Входные данные и полный рабочий сценарий · Результат запуска
Подтвердить последнюю позицию заказа
$hasLamp = $saved->offsetExists(1);После чтения заказа подтверждается наличие строки 1; значение читается отдельно.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::offsetGetЧитать позицию через [] или явный offsetGet.
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::offsetGet(mixed $key): mixedЧитать позицию через [] или явный offsetGet.
final public MongoDB\BSON\PackedArray::offsetGet(mixed $key): mixedПараметры
| Параметр | Смысл |
|---|---|
| $key: mixed | Поддерживается только int. |
Результат
Значение индекса; BSON int64 остаётся MongoDB\BSON\Int64. Синтаксис $packed[0] вызывает этот механизм.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. Отсутствующий индекс вызывает RuntimeException; в 2.5.5 такой же класс исключения наблюдается для строкового ключа. Проверяйте тип входа до обращения.
Версии
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+.
Получить LAMP по целому индексу
$lamp = $slots->offsetGet(2); // LAMPТретий слот возвращает LAMP; строковый ключ "0" специально отклонён в том же запуске.
Входные данные и полный рабочий сценарий · Результат запуска
Прочитать строку результата по []
$sku = $saved[0]->get('sku');Квадратные скобки выбирают первую позицию, get("sku") — её поле.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::offsetSetРазобрать запрет изменения PackedArray и правильную замену.
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::offsetSet(mixed $key, mixed $value): voidРазобрать запрет изменения PackedArray и правильную замену.
final public MongoDB\BSON\PackedArray::offsetSet(mixed $key, mixed $value): voidПараметры
| Параметр | Смысл |
|---|---|
| $key: mixed | Позиция, которую попытались изменить. |
| $value: mixed | Новое значение попытки записи. |
Результат
Нормального успешного изменения нет; сигнатура void описывает интерфейс.
Ошибки и ограничения
Всегда выбрасывает MongoDB\Driver\Exception\LogicException: BSON-контейнер неизменяемый.
Версии
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+.
Перехватить попытку менять количество на месте
try { $original->offsetSet(0,4); }
catch (MongoDB\Driver\Exception\LogicException $e) { /* перейти к PHP-копии */ }Исходное количество остаётся 2; правильная новая версия строится через toPHP/fromPHP.
Входные данные и полный рабочий сценарий · Результат запуска
Не подменить товар через квадратные скобки
try { $packed[0] = ['id'=>999,'sku'=>'WRONG']; }
catch (MongoDB\Driver\Exception\LogicException $e) { /* запись отклонена */ }Постоянный ID первого товара остаётся 101. Читабельный [] не разрешает запись.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::offsetUnsetРазобрать запрет удаления позиции из неизменяемого BSON.
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::offsetUnset(mixed $key): voidРазобрать запрет удаления позиции из неизменяемого BSON.
final public MongoDB\BSON\PackedArray::offsetUnset(mixed $key): voidПараметры
| Параметр | Смысл |
|---|---|
| $key: mixed | Позиция, которую попытались удалить. |
Результат
Успешного удаления нет; метод объявлен void по контракту ArrayAccess.
Ошибки и ограничения
Всегда выбрасывает MongoDB\Driver\Exception\LogicException.
Версии
Доступен с ext-mongodb 1.17.0. Примеры рассчитаны на 2.5+.
Сохранить исходную строку LAMP
try { $original->offsetUnset(1); }
catch (MongoDB\Driver\Exception\LogicException $e) { /* исходный список сохранён */ }Второе количество остаётся 1.
Входные данные и полный рабочий сценарий · Результат запуска
Удалять сначала из PHP-копии
try { unset($packed[1]); }
catch (MongoDB\Driver\Exception\LogicException $e) { /* нельзя менять BSON на месте */ }Для настоящего изменения: toPHP → unset → осознанный array_values → fromPHP. Строка в текущем PackedArray остаётся.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::toPHPПолучить удобную PHP-структуру для обработки или новой версии.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::toPHP(?array $typeMap = null): array|objectПолучить удобную PHP-структуру для обработки или новой версии.
final public MongoDB\BSON\PackedArray::toPHP(?array $typeMap = null): array|objectПараметры
| Параметр | Смысл |
|---|---|
| $typeMap: ?array = null | Карта декодирования: root, document, array и fieldPaths. null/отсутствие оставляют стандартное преобразование. Для полностью обычных массивов задайте значения array. |
Результат
Декодированное значение PHP. Обычно BSON-массив становится array, вложенный документ — stdClass. BSON int64 из этого метода остаётся Int64.
Ошибки и ограничения
InvalidArgumentException, если пользовательский класс карты типов нельзя создать или он не реализует MongoDB\BSON\Unserializable. Ошибочные карты/аргументы отклоняются расширением.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Значения карты: array, object/stdClass, bson (только root/document/array, не fieldPaths) или конкретный класс Unserializable. fieldPaths задаёт отдельные пути, $ в пути обозначает элемент массива. Пользовательские классы и __pclass требуют понимания правил Persistable; для формы их не нужно вводить. Полное описание карты типов доступно в официальном разделе сериализации.
Создать редактируемую копию количеств
$editable = $original->toPHP(['root'=>'array','document'=>'array','array'=>'array']);
$editable[0] = 4;Меняется PHP-копия; исходный PackedArray не меняется.
Входные данные и полный рабочий сценарий · Результат запуска
Редактировать поле вложенного документа
$copy = $cart->toPHP(['root'=>'array','document'=>'array','array'=>'array']);
$copy[0]['quantity'] = 3;Явное document=>array позволяет использовать ["quantity"], а не свойства stdClass.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::toCanonicalExtendedJSONПолучить текст для обмена с сохранением BSON-типов.
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::toCanonicalExtendedJSON(): stringПолучить текст для обмена с сохранением BSON-типов.
final public MongoDB\BSON\PackedArray::toCanonicalExtendedJSON(): stringПараметры
Параметров нет.
Результат
Строка Canonical Extended JSON с явными представлениями типов, в частности разных числовых BSON-типов.
Ошибки и ограничения
Страница метода не перечисляет специальных исключений. Это преобразование валидного BSON-контейнера; последующий приём всё равно требует обработки ошибок и проверки схемы.
Версии
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+.
Более многословен, чем Relaxed. Имена Canonical не означают универсальную канонизацию для подписи произвольного JSON: здесь проверяется BSON-представление заданных данных.
Сохранить int64 при передаче счётчика
$canonical = $values->toCanonicalExtendedJSON();
$exact = MongoDB\BSON\PackedArray::fromJSON($canonical);42 остаётся Int64; в этом наборе исходные BSON-байты совпадают.
Входные данные и полный рабочий сценарий · Результат запуска
Передать одну строку корзины с явными типами
$canonical = $imported->toCanonicalExtendedJSON();Артикул, количество и список опций можно восстановить fromJSON; исходный контейнер не меняется.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::toRelaxedExtendedJSONСделать BSON-массив удобнее для чтения, учитывая потери разновидности типа.
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::toRelaxedExtendedJSON(): stringСделать BSON-массив удобнее для чтения, учитывая потери разновидности типа.
final public MongoDB\BSON\PackedArray::toRelaxedExtendedJSON(): stringПараметры
Параметров нет.
Результат
Строка Relaxed Extended JSON: предпочтение обычным JSON-примитивам за счёт точности информации о типах.
Ошибки и ограничения
Специальные исключения на странице не перечислены. Не обещает идентичные BSON-типы после обратного преобразования.
Версии
Доступен с ext-mongodb 1.20.0. Примеры рассчитаны на 2.5+.
Увидеть потерю признака int64
$relaxed = $values->toRelaxedExtendedJSON();
$readable = MongoDB\BSON\PackedArray::fromJSON($relaxed);Значение 42 сохраняется, но обратное чтение даёт PHP int/BSON int32 вместо исходного Int64.
Входные данные и полный рабочий сценарий · Результат запуска
Показать структуру строки при отладке
$relaxed = $imported->toRelaxedExtendedJSON();Получается читаемая строка с sku, quantity и options. Она не является HTML и экранируется при показе.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::__toStringПолучить сырые BSON-байты для сравнения или контейнера обмена.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::__toString(): stringПолучить сырые BSON-байты для сравнения или контейнера обмена.
final public MongoDB\BSON\PackedArray::__toString(): stringПараметры
Параметров нет.
Результат
Бинарная PHP-строка с BSON-представлением массива, не печатный JSON.
Ошибки и ограничения
Специальные исключения на странице не перечислены. Ошибки файловой записи/транспорта относятся к отдельным операциям, а не к успешному получению строки.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Встроенный PackedArray не имеет публичного fromBSON. Используйте Document-контейнер либо fromJSON для соответствующего текстового формата. Если транспорт текстовый, бинарные байты требуют отдельного согласованного кодирования.
Подтвердить неизменность исходной версии
$beforeBytes = (string)$original;
// После отклонённых изменений: (string)$original === $beforeBytes.У исходного списка те же байты; новая версия с количеством 4 отличается.
Входные данные и полный рабочий сценарий · Результат запуска
Сравнить восстановленный бинарный список
$raw = (string)$values;
$same = (string)$restored === $raw;Список из бинарного Document-конверта возвращает те же байты. В HTML выведены длина/хеш/hex, а не бинарный мусор.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\PackedArray::getIteratorСоздать объект последовательного обхода BSON-массива.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final public MongoDB\BSON\PackedArray::getIterator(): MongoDB\BSON\IteratorСоздать объект последовательного обхода BSON-массива.
final public MongoDB\BSON\PackedArray::getIterator(): MongoDB\BSON\IteratorПараметры
Параметров нет.
Результат
Iterator для всех позиций массива; его также использует foreach благодаря IteratorAggregate.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. UnexpectedValueException, если BSON-итератор невозможно инициализировать.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Каждый отдельный getIterator создаёт отдельный объект обхода. Не путайте его с сетевым Cursor запроса; уже полученное BSON-значение не запрашивается заново из MongoDB.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::__constructПолучить BSON-итератор от контейнера, не создавая неинициализированный объект.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
final private MongoDB\BSON\Iterator::__construct()Получить BSON-итератор от контейнера, не создавая неинициализированный объект.
final private MongoDB\BSON\Iterator::__construct()Параметры
Параметров нет.
Результат
Прямой вызов недоступен. Iterator создаётся Document::getIterator или PackedArray::getIterator.
Ошибки и ограничения
Закрытый конструктор запрещает new MongoDB\BSON\Iterator(); на уровне PHP это Error доступа.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
final-класс реализует PHP Iterator. BSON-массив даёт числовые ключи, BSON-документ — строковые. Источник данных определяет смысл ключа.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::currentПрочитать значение в текущем месте без продвижения.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
public MongoDB\BSON\Iterator::current(): mixedПрочитать значение в текущем месте без продвижения.
public MongoDB\BSON\Iterator::current(): mixedПараметры
Параметров нет.
Результат
Значение текущего элемента; BSON int64 возвращается как MongoDB\BSON\Int64.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. LogicException, если текущая позиция недействительна. Проверяйте valid до чтения.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Два current подряд читают то же место. Для продвижения нужен next. В сценарии этапов специально поймано чтение после конца.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::keyУзнать ключ текущего элемента, а не его значение.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
public MongoDB\BSON\Iterator::key(): string|intУзнать ключ текущего элемента, а не его значение.
public MongoDB\BSON\Iterator::key(): string|intПараметры
Параметров нет.
Результат
При обходе BSON-массива — int, при обходе BSON-документа — string.
Ошибки и ограничения
PHP.net документирует MongoDB\Driver\Exception\InvalidArgumentException при ошибке разбора аргументов. Передавайте значения объявленного типа; strict_types не превращает строку URL в проверенный индекс. LogicException, если позиция недействительна.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
В корзине ключ 1 — порядковая позиция LAMP, не SKU и не постоянный ID товара. При обходе Document ключом было бы имя поля, например sku.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::nextПерейти к следующему элементу после обработки текущего.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
public MongoDB\BSON\Iterator::next(): voidПерейти к следующему элементу после обработки текущего.
public MongoDB\BSON\Iterator::next(): voidПараметры
Параметров нет.
Результат
Значение не возвращается; меняется позиция итератора.
Ошибки и ограничения
Отдельные исключения на странице метода не перечислены. После продвижения за конец valid возвращает false; current/key тогда читать нельзя.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Отсутствующий next в while с valid оставит чтение той же позиции бесконечно. В foreach перемещение выполняется автоматически, дополнительный ручной next там не нужен.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::rewindВернуться к первому элементу для нового прохода.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
public MongoDB\BSON\Iterator::rewind(): voidВернуться к первому элементу для нового прохода.
public MongoDB\BSON\Iterator::rewind(): voidПараметры
Параметров нет.
Результат
Значение не возвращается. Позиция устанавливается в начало; для пустого контейнера valid остаётся false.
Ошибки и ограничения
Отдельные исключения на странице метода не перечислены. Повторный обход данных не должен автоматически означать повтор внешнего побочного действия.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
В обоих полных сценариях rewind выполняется перед ручным циклом и ещё раз после его окончания; проверяется возврат к первой записи.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
MongoDB\BSON\Iterator::validПроверить, разрешено ли сейчас читать current и key.
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+. · mongodb
public MongoDB\BSON\Iterator::valid(): boolПроверить, разрешено ли сейчас читать current и key.
public MongoDB\BSON\Iterator::valid(): boolПараметры
Параметров нет.
Результат
true для действительной позиции; false для конца или пустого контейнера.
Ошибки и ограничения
Отдельные исключения на странице не перечислены. false — штатное окончание обхода, а не ошибка базы данных.
Версии
Доступен с ext-mongodb 1.16.0. Примеры рассчитаны на 2.5+.
Это проверка положения итератора, не истинности текущего значения: элемент null/false/0 может занимать действительную позицию. Состояние сетевого соединения этим методом не проверяется.
Управлять очередностью этапов отправки
$it = $stages->getIterator();
$it->rewind();
while ($it->valid()) {
$step = [$it->key(), $it->current()];
$it->next();
}Результат: 0/pack, 1/label, 2/ship. После конца valid=false, чтение current/key запрещено.
Входные данные и полный рабочий сценарий · Результат запуска
Получить номер и документ каждой строки корзины
$it = $cart->getIterator();
$it->rewind();
while ($it->valid()) {
$row = [$it->key(), $it->current()->get('sku')];
$it->next();
}Два документа дают 0/CUP и 1/LAMP. После rewind снова доступна первая строка.
Входные данные и полный рабочий сценарий · Результат запуска
Общая модель списка и документов · BSON-документы и именованные поля
Источники и обсуждения
- MongoDB\BSON\PackedArray::__construct
- MongoDB\BSON\PackedArray::fromPHP
- MongoDB\BSON\PackedArray::fromJSON
- MongoDB\BSON\PackedArray::get
- MongoDB\BSON\PackedArray::has
- MongoDB\BSON\PackedArray::offsetExists
- MongoDB\BSON\PackedArray::offsetGet
- MongoDB\BSON\PackedArray::offsetSet
- MongoDB\BSON\PackedArray::offsetUnset
- MongoDB\BSON\PackedArray::toPHP
- MongoDB\BSON\PackedArray::toCanonicalExtendedJSON
- MongoDB\BSON\PackedArray::toRelaxedExtendedJSON
- MongoDB\BSON\PackedArray::__toString
- MongoDB\BSON\PackedArray::getIterator
- MongoDB\BSON\Iterator::__construct
- MongoDB\BSON\Iterator::current
- MongoDB\BSON\Iterator::key
- MongoDB\BSON\Iterator::next
- MongoDB\BSON\Iterator::rewind
- MongoDB\BSON\Iterator::valid
- PackedArray class and version changes
- BSON Iterator class
- Serialization and deserialization rules
- PackedArray implementation at ext-mongodb 2.5.5
- Install MongoDB extension
- MongoDB Community Windows ZIP installation
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


