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

Дерево руководства
Глава 143 · После первого каталога MongoDB, массивов и объектов
MongoDB: запросы, курсоры и управляемая запись через PHP-драйвер
Реальный ping, серверная выборка, типы курсора, insert/delete, matched/modified, условный остаток и частичный импорт.
Команда, очередь, курсор и результат записи
После первого каталога полезно понять, какие операции выполняет PHP-расширение под библиотекой. Здесь собираем запрос, читаем его курсор, различаем сохранённую правку и простой повтор, а затем разбираем неполный импорт. В каждом случае виден итог в данных, а не только имя класса драйвера.
Если MongoDB встречается впервые, начните с документа, коллекции, BSON и первого каталога. Здесь уже нужны массивы, вызов функций и объекты. new создаёт объект; стрелка → в схемах показывает движение данных, а -> в PHP вызывает метод объекта. В коде MongoDB\Driver\Query — полное имя класса: обратные слеши разделяют пространство имён.
- PHP-массив описывает условие и поля
- Query хранит описание
- Manager отправляет запрос MongoDB
- Сервер возвращает выбранные BSON-документы
- Cursor декодирует их в PHP
- foreach выводит нужные значения
| Объект | Что делает | Чего ещё не произошло |
|---|---|---|
| Manager | Хранит конфигурацию, управляет обменом | Конструктор не проверяет сеть |
| Command / Query | Описание команды / поиска | Создание не исполняет операцию |
| BulkWrite | Очередь insert/update/delete | Документы ещё не записаны |
| Cursor | Последовательное чтение ответа | Не обязан уже хранить весь ответ в PHP |
| WriteResult | Подтверждённые счётчики записи | Не содержит автоматически изменённый товар |
MongoDB\Driver — классы расширения mongodb, установленного в PHP. MongoDB\Client и методы коллекции insertOne/find относятся к отдельной Composer-библиотеке mongodb/mongodb. В этой главе Composer не требуется. Библиотека упрощает прикладной код; низкий уровень нужен, чтобы понимать точный результат, настройки курсора и обработку пакетных ошибок. Старый класс Mongo из ext/mongo сюда не относится.
Подготовить отдельный учебный запуск
Запуск: PHP 8.4+ CLI с mongodb 2.5+, локальный MongoDB 8.0, отдельная учебная база. Контрольное окружение пакета использует PHP 8.5.11 и mongodb 2.5.5. Настройка сервера и расширения — в первой главе. Распакуйте ZIP одного сценария, задайте PHPMAN_MONGODB_URI и PHPMAN_MONGODB_DATABASE, затем выполните php example.php. Точные команды есть в README.
В каждом архиве находятся example.php, md115-helper.php и README.txt. Helper принимает только один явно заданный 127.0.0.1:порт в URI, без учётных данных; это ограничение учебной программы, не MongoDB. Допустимы directConnection=true и retryWrites=false. Важно оставить локальный сервер доступным только на loopback. Для настоящего удалённого сервера требуются отдельно настроенные права и TLS.
Каждый запуск явно создаёт уникальную коллекцию mongodb115_driver_… и помечает её своей только после успеха create. finally удаляет только это точное имя; затем listCollections проверяет отсутствие. Существующие коллекции не изменяются. Права требуются на собственную учебную коллекцию, listCollections и buildInfo; настройки сервера и чужие данные не меняются.
Получить настоящий ответ сервера и обработать недоступность
Перед импортом каталога нужно узнать, отвечает ли именно MongoDB. Объект подключения может успешно создаться даже при недоступном сервисе: проверяем выполненную команду, а не наличие переменной.
Исходные данные
Работающий локальный сервер и новая пустая учебная коллекция. Второй адрес программа получает из собственного временного TCP-слушателя; он не обслуживает протокол MongoDB.
- Manager хранит адрес и параметры
- Command содержит ping = 1
- executeCommand обращается к серверу
- Cursor отдаёт документ ok = 1
- Другой локальный порт не отвечает как MongoDB → ConnectionException
Самая короткая полезная операция
$command = new MongoDB\Driver\Command(['ping' => 1]);
$cursor = $manager->executeCommand($database, $command);
$reply = $cursor->toArray();
echo (int) $reply[0]->ok; // 1Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| Проверка | Результат |
|---|---|
| ping | ok = 1 |
| Своя коллекция | найдена |
| Manager без MongoDB-ответа | создан |
| Команда без MongoDB-ответа | ConnectionException |
Как это работает
new создаёт объект. Command — описание команды; executeCommand отправляет её в указанную базу. В ответе ping поле ok имеет числовое значение 1. Cursor — объект для последовательного чтения документов, а toArray собирает их в массив. У ping ответ маленький, поэтому это удобно. После него listCollections с точным именем проверяет собственную коллекцию. Во второй части Manager успешно создаётся, а первая настоящая команда выбрасывает исключение. catch обрабатывает именно класс сетевого отказа; прочие ошибки не скрываются.
Границы и ошибки
Успешный ping не гарантирует наличие прав на запись или корректность будущего запроса. Время ожидания выбора сервера, соединения и сокета различается; эти параметры не являются единой гарантией «всё закончится за 200 мс». Учебный TCP-порт освобождается в finally. На странице показывается тип отказа, без текста с адресами и учётными данными.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
$ping=md115Command($manager,$database,['ping'=>1]);
$exists=md115Exists($manager,$database,$collection);
$listener=stream_socket_server('tcp://127.0.0.1:0',$errno,$error,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);
if($listener===false){throw new RuntimeException('Cannot reserve a local teaching port');}
$unavailableCaught=false; $constructed=false;
try {
$address=stream_socket_get_name($listener,false);
if($address===false){throw new RuntimeException('Cannot read local teaching port');}
$unavailable=new MongoDB\Driver\Manager('mongodb://'.$address,[
'directConnection'=>true,'retryReads'=>false,'retryWrites'=>false,
'serverSelectionTimeoutMS'=>200,'connectTimeoutMS'=>200,'socketTimeoutMS'=>200]);
$constructed=true;
try{$unavailable->executeCommand($database,new MongoDB\Driver\Command(['ping'=>1]));}
catch(MongoDB\Driver\Exception\ConnectionException $failure){$unavailableCaught=true;}
} finally {fclose($listener);}
$rows=[['ping',((float)$ping[0]['ok']===1.0)?'ok = 1':'нет'],['Своя коллекция',$exists?'найдена':'нет'],['Manager без MongoDB-ответа',$constructed?'создан':'нет'],['Команда без MongoDB-ответа',$unavailableCaught?'ConnectionException':'нет']];
$checks=['ping_received'=>(float)$ping[0]['ok']===1.0,'exact_collection_found'=>$exists,'constructor_is_lazy'=>$constructed,'unavailable_service_caught'=>$unavailableCaught];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-command-probe', ['Проверка', 'Результат'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-command-probe: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-command-probe: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Замените проверку существования на другое точное имя в своей учебной базе: ping останется успешным, а коллекция не найдётся. Объясните, почему это разные проверки.
Практический вопрос: Когда PHP-драйвер действительно соединяется с MongoDB. Автору нужно отложенное соединение. Исторический вопрос отделяем от современного Manager: проверяем реальную команду, а не создание объекта. Обсуждение задаёт ситуацию; правила сверены по официальным источникам, программа и данные написаны для этого урока.
Отобрать товары на сервере и выбрать форму PHP-результата
Экран каталога должен показать два дешёвых активных товара в наличии. Условия, порядок и поля задаём серверу, чтобы не вытягивать весь каталог в PHP ради последующей фильтрации.
Исходные данные
Четыре товара: Кружка 500 ₽ / остаток 4 / active; Лампа 900 ₽ / 0 / active; Тарелка 300 ₽ / 6 / active; Образец 100 ₽ / 8 / draft. У каждого есть вложенный документ dimensions.
- status = active и stock > 0
- projection оставляет ID, title, price
- sort: price, затем уникальный _id
- limit = 2
- foreach получает Тарелку и Кружку
Самая короткая полезная операция
$query = new MongoDB\Driver\Query(
['status' => 'active', 'stock' => ['$gt' => 0]],
['projection' => ['_id' => 1, 'title' => 1, 'price' => 1],
'sort' => ['price' => 1, '_id' => 1], 'limit' => 2]
);
$cursor = $manager->executeQuery($namespace, $query);
$cursor->setTypeMap(['root' => 'array']);
foreach ($cursor as $product) { echo $product['title'], "\n"; }Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| ID | Товар | Цена, руб. |
|---|---|---|
| 103 | Тарелка | 300 |
| 101 | Кружка | 500 |
Как это работает
Фильтр — ассоциативный массив правил: равенство задаётся значением, оператор $gt означает «больше». Его имя пишем в одинарных кавычках, чтобы PHP не искал переменную. projection определяет возвращаемые поля; _id включён явно. Число 1 в sort — возрастание, -1 — убывание. Дополнительный _id делает порядок одинаковых цен определённым. setTypeMap управляет формой декодирования BSON: root — верхний документ, document — вложенный документ, array — BSON-массив. По умолчанию обычные документы здесь stdClass, с картой — массивы. Отдельные свежие курсоры демонстрируют оба варианта и читают dimensions.width = 8. Строка "101" не совпадает с целочисленным _id 101; PHP-приведение типов сервер не выполняет.
Границы и ошибки
toArray материализует весь ответ в память: используйте его для ограниченной выборки, а большие потоки обрабатывайте foreach. batchSize управляет порциями, а не общим числом документов. Не начинайте второй обход уже продвинутого курсора: выполните запрос заново. Type map не превращает ObjectId в число или обычную строку и не меняет данные на сервере.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
md115Insert($manager,$namespace,[
['_id'=>101,'title'=>'Кружка','price'=>500,'stock'=>4,'status'=>'active','dimensions'=>['width'=>8]],
['_id'=>102,'title'=>'Лампа','price'=>900,'stock'=>0,'status'=>'active','dimensions'=>['width'=>20]],
['_id'=>103,'title'=>'Тарелка','price'=>300,'stock'=>6,'status'=>'active','dimensions'=>['width'=>24]],
['_id'=>104,'title'=>'Образец','price'=>100,'stock'=>8,'status'=>'draft','dimensions'=>['width'=>5]]]);
$filter=['status'=>'active','stock'=>['$gt'=>0]];
$options=['projection'=>['_id'=>1,'title'=>1,'price'=>1],'sort'=>['price'=>1,'_id'=>1],'limit'=>2,'maxTimeMS'=>1000];
$cursor=$manager->executeQuery($namespace,new MongoDB\Driver\Query($filter,$options));
$cursor->setTypeMap(['root'=>'array','document'=>'array','array'=>'array']);
$rows=[];
foreach($cursor as $document){$rows[]=[$document['_id'],$document['title'],$document['price']];}
$objectCursor=$manager->executeQuery($namespace,new MongoDB\Driver\Query(['_id'=>101],['limit'=>1,'maxTimeMS'=>1000]));
$object=$objectCursor->toArray()[0];
$arrayCursor=$manager->executeQuery($namespace,new MongoDB\Driver\Query(['_id'=>101],['limit'=>1,'maxTimeMS'=>1000]));
$arrayCursor->setTypeMap(['root'=>'array','document'=>'array','array'=>'array']);
$array=$arrayCursor->toArray()[0];
$empty=md115Read($manager,$namespace,['_id'=>'101'],['projection'=>['_id'=>1],'limit'=>1]);
$checks=['server_filter_sort_limit'=>$rows===[[103,'Тарелка',300],[101,'Кружка',500]],'default_is_object'=>$object instanceof stdClass && $object->dimensions instanceof stdClass,'map_controls_nested_document'=>is_array($array) && is_array($array['dimensions']) && $array['dimensions']['width']===8,'id_type_is_not_loose'=>$empty===[],'projected_fields_only'=>array_keys($document)===['_id','title','price']];
$details=['default_type'=>get_debug_type($object),'mapped_type'=>get_debug_type($array),'nested_width'=>$array['dimensions']['width'],'string_id_matches'=>count($empty)];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-filtered-cursor', ['ID', 'Товар', 'Цена, руб.'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-filtered-cursor: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-filtered-cursor: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Поставьте limit = 1: останется Тарелка. Затем смените price на -1: первой станет Кружка. Меняйте Query, сохраняя обработку результата одинаковой.
Практический вопрос: Массивы и объекты в ответе MongoDB PHP. Приложение путает доступ через -> и через ключи массива. Показываем явную карту типов и вложенные документы. Обсуждение задаёт ситуацию; правила сверены по официальным источникам, программа и данные написаны для этого урока.
Записать каталог и удалить только выбранные черновики
Импорт добавляет товары и временные черновики. Нужно подтвердить число записей, затем удалить конкретный устаревший макет и остальные черновики, сохранив активные товары.
Исходные данные
Пустая коллекция. Первый пакет добавляет активные ID 101–103, второй — черновики 201–203. Фильтр первого удаления содержит ID 201 и status = draft; второго — только status = draft.
- insert добавляет инструкции в BulkWrite
- executeBulkWrite выполняет пакет
- WriteResult сообщает inserted = 3
- delete с limit = true удаляет ID 201
- delete с limit = false удаляет два оставшихся draft
- Чтение подтверждает ID 101, 102, 103
Самая короткая полезная операция
$bulk = new MongoDB\Driver\BulkWrite;
$id = $bulk->insert(['_id' => 101, 'title' => 'Кружка']);
$result = $manager->executeBulkWrite($namespace, $bulk);
echo $id; // 101: ID в подготовленной операции
echo $result->getInsertedCount(); // 1: подтверждение сервераЭтот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| Операция | Количество |
|---|---|
| Добавлен каталог | 3 |
| Добавлены черновики | 3 |
| Удалён выбранный черновик | 1 |
| Удалены оставшиеся черновики | 2 |
| Сохранены активные товары | 3 |
Как это работает
BulkWrite — список инструкций на запись. Вызов insert ещё не отправляет документ; возвращённый ID означает подготовленную идентичность, а не подтверждённое сохранение. Ответ WriteResult получаем после executeBulkWrite. Для каждой следующей отправки создаём новый BulkWrite. В delete значение limit — логическое: true ограничивает одной найденной записью, false разрешает все совпадения. Это не произвольное SQL LIMIT 20. Удаление по уникальному _id выбирает конкретный документ; дополнительный status защищает от удаления уже опубликованного товара. Счётчик читается после исполнения, а контрольное чтение показывает сохранённые активные ID.
Границы и ошибки
Пустой фильтр delete означает все документы коллекции. Здесь это не используется. Не передавайте фильтр из HTTP-запроса без проверки структуры и полномочий. При конфликте ID пакет может выполниться частично; отдельный сценарий ниже показывает такой ответ. w=0 не позволяет достоверно прочитать счётчики: используется w=1.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
$bulk=new MongoDB\Driver\BulkWrite(['ordered'=>true]);
$id=$bulk->insert(['_id'=>101,'title'=>'Кружка','status'=>'active']);
$bulk->insert(['_id'=>102,'title'=>'Лампа','status'=>'active']);
$bulk->insert(['_id'=>103,'title'=>'Тарелка','status'=>'active']);
$catalog=$manager->executeBulkWrite($namespace,$bulk);
$drafts=new MongoDB\Driver\BulkWrite;
$drafts->insert(['_id'=>201,'title'=>'Устаревший макет','status'=>'draft']);
$drafts->insert(['_id'=>202,'title'=>'Макет A','status'=>'draft']);
$drafts->insert(['_id'=>203,'title'=>'Макет B','status'=>'draft']);
$draftResult=$manager->executeBulkWrite($namespace,$drafts);
$one=new MongoDB\Driver\BulkWrite;
$one->delete(['_id'=>201,'status'=>'draft'],['limit'=>true]);
$oneResult=$manager->executeBulkWrite($namespace,$one);
$remainingDrafts=new MongoDB\Driver\BulkWrite;
$remainingDrafts->delete(['status'=>'draft'],['limit'=>false]);
$manyResult=$manager->executeBulkWrite($namespace,$remainingDrafts);
$remaining=md115Read($manager,$namespace,[],['projection'=>['_id'=>1],'sort'=>['_id'=>1],'limit'=>10]);
$rows=[['Добавлен каталог',$catalog->getInsertedCount()],['Добавлены черновики',$draftResult->getInsertedCount()],['Удалён выбранный черновик',$oneResult->getDeletedCount()],['Удалены оставшиеся черновики',$manyResult->getDeletedCount()],['Сохранены активные товары',count($remaining)]];
$checks=['explicit_id_returned'=>$id===101,'catalog_inserted'=>$catalog->getInsertedCount()===3,'drafts_inserted'=>$draftResult->getInsertedCount()===3,'targeted_delete'=>$oneResult->getDeletedCount()===1,'filtered_multi_delete'=>$manyResult->getDeletedCount()===2,'active_ids_preserved'=>array_column($remaining,'_id')===[101,102,103]];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-batch-insert', ['Операция', 'Количество'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-batch-insert: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-batch-insert: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Измените один из черновиков на active до удаления по status: он должен сохраниться, а getDeletedCount стать меньше. Сформулируйте нужный фильтр до запуска удаления.
Отличить сохранённую правку, повтор и отсутствующий товар
Форма редактирования товара должна различать новую цену, повторное сохранение той же цены и неверный ID. Один нулевой счётчик не описывает все три ситуации.
Исходные данные
ID 101: Кружка, price = 500, status = active. Отправляются цены 650, снова 650, затем 650 для несуществующего ID 999.
- Фильтр ищет _id
- Оператор $set меняет только price
- matched считает совпавшие документы
- modified считает фактически изменённые
- Контрольное чтение: price 650, title/status сохранены
Самая короткая полезная операция
$bulk->update(['_id' => 101], ['$set' => ['price' => 650]],
['multi' => false, 'upsert' => false]);
$result = $manager->executeBulkWrite($namespace, $bulk);
echo $result->getMatchedCount(); // 1: товар найден
echo $result->getModifiedCount(); // 1: цена измениласьЭтот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| Действие | matched | modified |
|---|---|---|
| Изменить цену | 1 | 1 |
| Повторить ту же цену | 1 | 0 |
| Изменить отсутствующий товар | 0 | 0 |
Как это работает
$set задаёт отдельное поле, сохраняя остальные. matched = 1 и modified = 0 здесь означают, что товар найден, но цена уже была 650; это успешный повтор неизменяющего запроса. При ID 999 оба счётчика нулевые: upsert = false запрещает создавать товар из неудачного редактирования. Если передать обычный документ без операторов вместо $set, это будет замена документа — пропущенные поля не сохранятся. В уроке такой замены нет. Код после каждого запроса читает оба значения, а в конце проверяет сам товар.
Границы и ошибки
Счётчики относятся ко всему отправленному пакету. Для понятного решения формы здесь ровно одна операция. При upsert нужна отдельная интерпретация getUpsertedCount и getUpsertedIds; inserted не заменяет их. Между конкурентными чтениями товар может измениться: для защиты формы используйте ожидаемую версию в фильтре.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
md115Insert($manager,$namespace,[['_id'=>101,'title'=>'Кружка','price'=>500,'status'=>'active']]);
$rows=[]; $counts=[];
foreach([['Изменить цену',101,650],['Повторить ту же цену',101,650],['Изменить отсутствующий товар',999,650]] as [$label,$id,$price]){
$bulk=new MongoDB\Driver\BulkWrite;
$bulk->update(['_id'=>$id],['$set'=>['price'=>$price]],['multi'=>false,'upsert'=>false]);
$result=$manager->executeBulkWrite($namespace,$bulk);
$pair=[$result->getMatchedCount(),$result->getModifiedCount()];
$counts[]=$pair; $rows[]=[$label,...$pair];
}
$product=md115Read($manager,$namespace,['_id'=>101],['projection'=>['_id'=>1,'title'=>1,'price'=>1,'status'=>1],'limit'=>1])[0];
$checks=['changed_repeat_missing_counts'=>$counts===[[1,1],[1,0],[0,0]],'new_price_saved'=>$product['price']===650,'other_fields_preserved'=>$product['title']==='Кружка' && $product['status']==='active','missing_not_upserted'=>md115Read($manager,$namespace,['_id'=>999],['limit'=>1])===[]];
$details=['final_product'=>$product];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-update-counts', ['Действие', 'matched', 'modified'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-update-counts: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-update-counts: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Верните цену на 500: получите 1/1. Отправьте 500 ещё раз: 1/0. Не выводите пользователю «товар не найден», опираясь только на modified.
Уменьшить остаток только при достаточном количестве
На складе три кружки. Два запроса последовательно хотят забрать по две. Проверка остатка и уменьшение должны относиться к одной серверной операции, чтобы количество не стало отрицательным.
Исходные данные
Один документ: _id = 101, stock = 3. Два независимых запроса по 2 единицы; количество заранее является проверенным положительным целым.
- Фильтр: _id 101 и stock ≥ 2
- Оператор $inc прибавляет -2
- Первый запрос: 3 → 1
- Второй: 1 не удовлетворяет ≥ 2
- matched 0, остаток остаётся 1
Самая короткая полезная операция
$quantity = 2;
$bulk->update(
['_id' => 101, 'stock' => ['$gte' => $quantity]],
['$inc' => ['stock' => -$quantity]],
['multi' => false, 'upsert' => false]
); // проверка и изменение одного документа — одна операцияЭтот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| Запрос | Количество | matched | modified | Осталось | Решение |
|---|---|---|---|---|---|
| Попытка 1 | 2 | 1 | 1 | 1 | принято |
| Попытка 2 | 2 | 0 | 0 | 1 | не выполнено |
Как это работает
$gte означает «больше или равно». $inc изменяет числовое поле на указанную величину. MongoDB атомарно проверяет фильтр и изменяет один документ; отдельные «прочитать остаток → вычислить PHP → записать новое число» могут потерять параллельное изменение. В ответе matched = 1 означает принятую условную правку. matched = 0 может означать недостаточный остаток, отсутствующий товар или другое несовпавшее условие; текст для клиента выбирается по договору приложения. Последующее чтение здесь показывает результат урока, оно не является частью атомарного изменения.
Границы и ошибки
Это последовательная демонстрация условия, не нагрузочный тест гонки. Атомарность одного документа не объединяет запись заказа и списание нескольких товаров в транзакцию. Повтор запроса не является автоматически безопасным: если остатка хватит, он спишет ещё раз. Идемпотентность платежей/заказов требует отдельного ключа и модели. upsert выключен.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
md115Insert($manager,$namespace,[['_id'=>101,'title'=>'Кружка','stock'=>3]]);
$rows=[]; $pairs=[];
foreach([2,2] as $attempt=>$quantity){
$bulk=new MongoDB\Driver\BulkWrite;
$bulk->update(['_id'=>101,'stock'=>['$gte'=>$quantity]],['$inc'=>['stock'=>-$quantity]],['multi'=>false,'upsert'=>false]);
$result=$manager->executeBulkWrite($namespace,$bulk);
$stock=md115Read($manager,$namespace,['_id'=>101],['projection'=>['_id'=>0,'stock'=>1],'limit'=>1])[0]['stock'];
$pair=[$result->getMatchedCount(),$result->getModifiedCount()]; $pairs[]=$pair;
$rows[]=['Попытка '.($attempt+1),$quantity,...$pair,$stock,$pair[0]===1?'принято':'не выполнено'];
}
$checks=['only_first_update_matches'=>$pairs===[[1,1],[0,0]],'stock_never_negative'=>$rows[0][4]===1 && $rows[1][4]===1,'request_did_not_create_product'=>count(md115Read($manager,$namespace,[],['projection'=>['_id'=>1],'limit'=>10]))===1];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-conditional-stock', ['Запрос', 'Количество', 'matched', 'modified', 'Осталось', 'Решение'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-conditional-stock: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-conditional-stock: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Измените второй запрос на одну единицу: он пройдёт, итог станет нулём. Затем попробуйте запросить ещё одну: ожидайте 0/0 и остаток 0.
Увидеть частичный результат пакета при конфликте ID
В импортируемом пакете повторился ID. Важно увидеть, какие документы уже сохранены и будет ли обработан хвост, чтобы не назвать весь импорт откатанным и не повторить его вслепую.
Исходные данные
Сначала сохраняются ID 102 и 202. Затем две группы: 101, 102, 103 с ordered = true; 201, 202, 203 с ordered = false. Второй insert конфликтует с уже существующим ID при любом порядке исполнения.
- Первая запись успешна
- Вторая получает duplicate key 11000
- ordered = true останавливает хвост
- ordered = false продолжает независимые операции
- Из исключения читаем частичный WriteResult
- Query подтверждает фактически сохранённые ID
Самая короткая полезная операция
// В коллекции уже есть _id = 202.
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
$bulk->insert(['_id' => 201]);
$bulk->insert(['_id' => 202]); // конфликт существующего _id
$bulk->insert(['_id' => 203]);
try { $manager->executeBulkWrite($namespace, $bulk); }
catch (MongoDB\Driver\Exception\BulkWriteException $error) {
echo $error->getWriteResult()->getInsertedCount(); // 2
}Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.
Что получится
| Режим | Код ошибки | Индекс операции | Вставлено | ID на сервере |
|---|---|---|---|---|
| ordered = true | 11000 | 1 | 1 | 101, 102 |
| ordered = false | 11000 | 1 | 2 | 201, 202, 203 |
Как это работает
ordered = true сохраняет порядок и прекращает дальнейшие операции при ошибке записи. false разрешает продолжать; ошибка всё равно сообщается. Индекс операции начинается с нуля: 1 — второй insert. catch в полной программе проверяет ожидаемые код, индекс и отсутствие write concern error; другие отказы пробрасываются. getInsertedCount берётся из getWriteResult исключения, поэтому мы не теряем подтверждённый частичный успех. Проверка документов отдельно подтверждает число. Этот BulkWrite после попытки не запускают снова.
Границы и ошибки
BulkWrite сам по себе не транзакция. ordered = false не гарантирует исходный порядок или универсальную параллельность. Если операции зависят друг от друга, менять ordered ради скорости нельзя. Потеря соединения может оставить неопределённость результата; это другая ситуация, чем полученный серверный duplicate key. Для возобновления импорта нужны стабильные идентификаторы и журнал обработки.
Полная самостоятельная программа и архив
<?php
declare(strict_types=1);
require __DIR__.'/md115-helper.php';
[$manager,$database]=md115Environment();
$server=md115Command($manager,$database,['buildInfo'=>1])[0]['version'];
$runtime=['php'=>PHP_VERSION,'extension'=>phpversion('mongodb'),'server'=>$server];
$collection='mongodb115_driver_'.bin2hex(random_bytes(8));
$namespace=$database.'.'.$collection; $owned=false; $details=[];
try {
if(md115Exists($manager,$database,$collection)){throw new RuntimeException('Random fixture name already exists');}
md115Command($manager,$database,['create'=>$collection]);
$owned=true;
$rows=[]; $observed=[];
foreach([[true,100],[false,200]] as [$ordered,$base]){
md115Insert($manager,$namespace,[['_id'=>$base+2,'title'=>'Ранее сохранённый','group'=>$base]]);
$bulk=new MongoDB\Driver\BulkWrite(['ordered'=>$ordered]);
$bulk->insert(['_id'=>$base+1,'title'=>'Первый','group'=>$base]);
$bulk->insert(['_id'=>$base+2,'title'=>'Дубликат','group'=>$base]);
$bulk->insert(['_id'=>$base+3,'title'=>'Последний','group'=>$base]);
$caught=false; $errorCode=null; $errorIndex=null; $inserted=null;
try{$manager->executeBulkWrite($namespace,$bulk);}
catch(MongoDB\Driver\Exception\BulkWriteException $error){
$partial=$error->getWriteResult(); $errors=$partial->getWriteErrors();
if(count($errors)!==1 || $errors[0]->getCode()!==11000 || $errors[0]->getIndex()!==1 || $partial->getWriteConcernError()!==null){throw $error;}
$caught=true; $errorCode=$errors[0]->getCode(); $errorIndex=$errors[0]->getIndex();
$inserted=$partial->getInsertedCount();
}
$documents=md115Read($manager,$namespace,['group'=>$base],['projection'=>['_id'=>1],'sort'=>['_id'=>1],'limit'=>10]);
$ids=array_column($documents,'_id');
$observed[]=[$caught,$inserted,$ids,$errorCode,$errorIndex];
$rows[]=[$ordered?'ordered = true':'ordered = false',$errorCode,$errorIndex,$inserted,implode(', ',$ids)];
}
$checks=['ordered_partial_result'=>$observed[0]===[true,1,[101,102],11000,1],'unordered_partial_result'=>$observed[1]===[true,2,[201,202,203],11000,1],'saved_documents_confirm_counts'=>count(md115Read($manager,$namespace,[],['projection'=>['_id'=>1],'limit'=>10]))===5];
} finally {
if($owned){md115Command($manager,$database,['drop'=>$collection]);}
}
$checks['owned_collection_removed']=!md115Exists($manager,$database,$collection);
md115Report('mongo115-driver-partial-bulk', ['Режим', 'Код ошибки', 'Индекс операции', 'Вставлено', 'ID на сервере'], $rows, $checks, $runtime, $details);
echo 'mongo115-driver-partial-bulk: saved result.html and result.json
';
Ожидаемый результат
mongo115-driver-partial-bulk: saved result.html and result.json
Откройте result.html после php example.php. Подготовка документов, helper, проверки и уборка своей коллекции включены в архив.
Открыть фактический HTML-результат · Скачать результат JSON
Попробуйте сами. Уберите дублирующий ID: обе группы сохранят по три документа. Затем поместите конфликт в первую позицию и предскажите разницу двух режимов до запуска.
Практический вопрос: Почему ordered=false всё равно возвращает duplicate key. Продолжение независимых операций ошибочно принимают за отсутствие ошибки. Показываем исключение, частичные счётчики и сохранённые ID. Обсуждение задаёт ситуацию; правила сверены по официальным источникам, программа и данные написаны для этого урока.
16 методов: контракты и два применения каждого
Выберите объект по задаче: соединение и исполнение, описание запросов, очередь записи, чтение курсора, проверка счётчиков. У каждой карточки есть сигнатура, параметры, ошибки, версия и две привязки к фактически исполняемым сценариям.
| Метод | Зачем нужен |
|---|---|
| MongoDB\Driver\Manager::__construct | Настроить адрес и поведение драйвера; настоящий обмен начинается при операции. |
| MongoDB\Driver\Manager::executeCommand | Выполнить команду базы и получить её документы ответа. |
| MongoDB\Driver\Manager::executeQuery | Отправить фильтр коллекции и читать выбранные документы. |
| MongoDB\Driver\Manager::executeBulkWrite | Отправить накопленные изменения и получить подтверждённые счётчики. |
| MongoDB\Driver\Command::__construct | Описать команду отдельно от её отправки. |
| MongoDB\Driver\Query::__construct | Собрать фильтр и серверные ограничения выдачи. |
| MongoDB\Driver\BulkWrite::__construct | Создать очередь операций с определённой политикой ошибок. |
| MongoDB\Driver\BulkWrite::insert | Добавить документ в очередь и получить его будущий ID. |
| MongoDB\Driver\BulkWrite::update | Добавить изменение выбранных документов без неявного создания товара. |
| MongoDB\Driver\BulkWrite::delete | Подготовить ограниченное удаление выбранного документа или группы. |
| MongoDB\Driver\Cursor::setTypeMap | Получать BSON-документы в нужной PHP-форме без JSON-перекодирования. |
| MongoDB\Driver\Cursor::toArray | Собрать небольшой ответ курсора в PHP-массив для дальнейшего обращения. |
| MongoDB\Driver\WriteResult::getInsertedCount | Узнать число подтверждённых insert в выполненном пакете. |
| MongoDB\Driver\WriteResult::getMatchedCount | Отделить найденный документ от фактически изменённого. |
| MongoDB\Driver\WriteResult::getModifiedCount | Посчитать документы, в которых действительно изменились значения. |
| MongoDB\Driver\WriteResult::getDeletedCount | Подтвердить количество удалённых документов, не предполагая его заранее. |
Применить результат в своём сервисе
Отправляйте в базу именно тот фильтр, поля и предел, которые нужны экрану. При записи отделяйте подготовку операции, подтверждение сервера и фактическое состояние документов. При ошибке импорта учитывайте частичный результат; не придумывайте откат, которого не было.
Продолжить прикладной маршрут можно в каталоге через PHP Library. Сравнить принцип выборки с реляционной базой — в фильтрах MySQL, а независимость атомарного документа от общей бизнес-транзакции — с транзакциями и конкурентными изменениями. Sessions, транзакции MongoDB, индексы, aggregation, GridFS, Change Streams и полная модель BSON — самостоятельные следующие темы; эти 16 карточек не объявляют весь MongoDB-справочник завершённым.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
MongoDB\Driver\Manager::__constructНастроить адрес и поведение драйвера; настоящий обмен начинается при операции.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Manager::__construct(?string $uri = null, ?array $uriOptions = null, ?array $driverOptions = null)Настроить адрес и поведение драйвера; настоящий обмен начинается при операции.
MongoDB\Driver\Manager::__construct(?string $uri = null, ?array $uriOptions = null, ?array $driverOptions = null)Параметры
| Параметр | Назначение |
|---|---|
| uri | Адрес mongodb://; без значения 127.0.0.1:27017. Учётные компоненты кодируют отдельно. |
| uriOptions | Параметры соединения, имеют приоритет над URI: таймауты, authSource, TLS, read/write concern, retryReads/retryWrites, directConnection, replicaSet. |
| driverOptions | Параметры самого драйвера, например disableClientPersistence или autoEncryption; не произвольные queryOptions. |
Возвращаемое значение
Конструктор создаёт Manager. Сетевого ввода-вывода здесь нет; готовность проверяют командой.
Ошибки и ограничения
InvalidArgumentException при неверных аргументах, RuntimeException при неверном URI. Сетевые и auth-ошибки возникают при операции. TLS-проверки рабочего сервера не отключают.
Версии
С mongodb 1.0. В 2.0 убраны старые safe/ssl и ряд TLS driverOptions: используйте современные w/tls и URI-параметры. На Unix не переиспользуйте Manager после fork без exec.
Проверка готовности перед импортом
$manager = new MongoDB\Driver\Manager($uri, ['serverSelectionTimeoutMS' => 1000]);
$reply = $manager->executeCommand($database, new MongoDB\Driver\Command(['ping' => 1]));Что получит приложение. Сам Manager создан; выполненный ping возвращает ok = 1.
Исходные данные, полная программа и разбор · Фактический результат
Отказ зависимого сервиса
$unavailable = new MongoDB\Driver\Manager('mongodb://'.$address, ['connectTimeoutMS' => 200, 'serverSelectionTimeoutMS' => 200]);
// В полном примере адрес занят собственным TCP-слушателем без MongoDB.Что получит приложение. Конструктор проходит, executeCommand получает ConnectionException. Приложение различает конфигурацию и доступность.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
Все группы параметров конструктора и отдельные режимы
Справочная область ниже шире шести локальных сценариев. Значения по умолчанию относятся к расширению; поддержка конкретной опции зависит от его версии и сервера. Опции пулов других драйверов не переносите сюда: ext-mongodb не реализует их connection pools.
| uriOptions | Тип | Смысл / ограничения |
|---|---|---|
| appname | string | Имя приложения в диагностике; до 128 символов. |
| authMechanism / authMechanismProperties | string / array | Механизм и его строковые свойства. |
| authSource | string | База учётной записи; выше defaultAuthDb, иначе admin. Для внешнего хранилища — $external. |
| username / password | string | Учётные данные отдельно от URL-кодирования URI. |
| compressors / zlibCompressionLevel | string / int | Приоритет компрессоров через запятую; уровень действует только для zlib. |
| connectTimeoutMS / socketTimeoutMS | int | Соединение / обмен сокета, миллисекунды; значения по умолчанию 10000 / 300000. |
| serverSelectionTimeoutMS / serverSelectionTryOnce | int / bool | Выбор сервера: 30000 мс; одна попытка сканирования по умолчанию true. |
| heartbeatFrequencyMS / socketCheckIntervalMS | int | Проверка топологии: 60000 мс (минимум 500); проверка простаивавшего сокета: 5000 мс. |
| directConnection / replicaSet | bool / string | Прямой адрес либо обнаружение участников указанного replica set. |
| loadBalanced | bool | Балансировщик: один host, без replicaSet и directConnection=true; по умолчанию false. |
| localThresholdMS | int | Окно выбора по задержке, 15 мс. |
| maxStalenessSeconds | int | Предел отставания secondary; если задан — int32, минимум 90 секунд. |
| readPreference / readPreferenceTags | string / array | Режим чтения (primary) и наборы тегов. |
| readConcernLevel | string | Уровень изоляции чтения. |
| w / wTimeoutMS / journal | int|string / int|string / bool | Подтверждение записи, его таймаут (неотрицательный int32), требование журнала. |
| retryReads / retryWrites | bool | Повтор некоторых временных отказов; оба true по умолчанию, зависят от топологии/операции. |
| enableOverloadRetargeting / maxAdaptiveRetries | bool / int | Повторный выбор сервера при SystemOverloadedError; false / положительное число, default 2. |
| srvMaxHosts / srvServiceName | int / string | Предел SRV-узлов (0 без ограничения), сервис mongodb. |
| tls | bool | TLS, по умолчанию false; другие TLS-опции могут включить его автоматически. |
| tlsCAFile / tlsCertificateKeyFile / tlsCertificateKeyFilePassword | string | CA, клиентский сертификат/ключ (при необходимости объединённый файл), пароль ключа. |
| tlsAllowInvalidCertificates / tlsAllowInvalidHostnames / tlsInsecure | bool | Ослабляют проверку; false. tlsInsecure объединяет две первые уступки; не применять для рабочего сервера. |
| tlsDisableCertificateRevocationCheck / tlsDisableOCSPEndpointCheck | bool | Отключают отзыв сертификата / запрос OCSP; false. |
| driverOptions | Тип | Смысл |
|---|---|---|
| ca_dir / crl_file | string | Хешированный каталог CA / файл списка отзыва. |
| disableClientPersistence | bool | false; true создаёт отдельный непостоянный libmongoc client и закрывает его с Manager. Обычно не требуется. |
| driver | array | Метаданные name/version/platform верхней библиотеки; handshake ограничен 512 байтами. |
| serverApi | MongoDB\Driver\ServerApi | Выбор стабильной серверной API-версии; без опции не объявлена. |
| autoEncryption | array | Настройки ниже; шифрование не включается нашими учебными программами. |
| autoEncryption / вложенные поля | Тип | Смысл |
|---|---|---|
| keyVaultClient / keyVaultNamespace | Manager / string | Отдельный клиент (иначе текущий) / обязательная база.коллекция ключей. |
| kmsProviders | array | Хотя бы один провайдер: aws, azure, gcp, kmip, local. |
| aws | array | accessKeyId, secretAccessKey; необязательный sessionToken. |
| azure | array | tenantId, clientId, clientSecret; identityPlatformEndpoint по умолчанию login.microsoftonline.com. |
| gcp | array | email, privateKey (base64|BSON Binary); endpoint по умолчанию oauth2.googleapis.com. |
| kmip / local | array | endpoint / key (мастер-ключ 96 байт, base64|BSON Binary). |
| tlsOptions | array | По KMS-провайдеру: tlsCaFile, tlsCertificateKeyFile, tlsCertificateKeyFilePassword, tlsDisableOCSPEndpointCheck. |
| schemaMap / encryptedFieldsMap | array|object | Схемы по namespace; одна коллекция не может быть в обеих картах. Локальная карта исключает доверие подменённой серверной схеме. |
| bypassAutoEncryption / bypassQueryAnalysis | bool | false; отключение автоматического шифрования / анализа команды. Автодешифрование возможно и при bypassAutoEncryption. |
| extraOptions | array | Управление mongocryptd и crypt_shared — перечислено ниже. |
| mongocryptdURI / mongocryptdBypassSpawn | string / bool | mongodb://localhost:27020 / false; адрес процесса / запрет его запуска. |
| mongocryptdSpawnPath / mongocryptdSpawnArgs | string / array | Путь (иначе системный) / аргументы (default --idleShutdownTimeoutSecs=60). |
| cryptSharedLibPath / cryptSharedLibRequired | string / bool | Путь библиотеки / обязательность загрузки (false). |
Пустой документ aws/azure/gcp включает получение автоматических учётных данных при поддерживаемой конфигурации. Автоматическое шифрование применяется к коллекциям, требует listCollections и дополнительных компонентов; команды базы/представления имеют ограничения. Локальная schemaMap описывает шифрование, а не произвольную серверную валидацию. Явное шифрование/дешифрование и автоматическое дешифрование доступны отдельно от enterprise-автошифрования. Эти режимы здесь справочно перечислены, но не установлены и не проверены примерами.
URI может содержать несколько узлов replica set, mongos, Unix-сокет (путь кодируют rawurlencode) и authSource. Учётные компоненты URI кодируют отдельно; база в пути при отсутствии учётной записи сама по себе не выбирает рабочую коллекцию. Учебный helper сознательно разрешает только loopback; это не ограничение Manager.
| Версия mongodb | Изменения конструктора |
|---|---|
| 1.1 / 1.2 | URI стал необязательным; затем default 127.0.0.1, appname/TLS-параметры, отказ от PHP Streams; connectTimeoutMS 10 секунд. |
| 1.3 / 1.4 / 1.5 | authMechanism(Properties) в uriOptions; компрессия/retryWrites; wTimeoutMS всегда проверяется. |
| 1.6 / 1.7 | retryReads и современные TLS URI-поля; autoEncryption и автоматическое включение TLS соответствующими опциями. |
| 1.8 / 1.10 | directConnection, проверки отзыва, driver; затем disableClientPersistence, Azure/GCP, base64-ключи. |
| 1.11 / 1.12 / 1.13 | loadBalanced; KMIP и KMS TLS; SRV-ограничения. |
| 1.14 / 1.15 / 1.16 | queryable encryption/crypt_shared; автоматические AWS credentials; sessionToken, Azure/GCP credentials, OCSP для KMS. |
| 2.0 | canonicalizeHostname → authMechanismProperties.CANONICALIZE_HOST_NAME; gssapiServiceName → SERVICE_NAME; safe → w/wTimeoutMS; ssl → tls. Старые allow_invalid_hostname/ca_file/context/pem_file/pem_pwd/weak_cert_validation заменены современными TLS URI-полями. |
Настройка конкретной топологии и шифрования: параметры URI MongoDB и официальное руководство по шифрованию PHP. Они нужны для отдельного развёртывания; локальный учебный сценарий не подтверждает эти конфигурации.
MongoDB\Driver\Manager::executeCommandВыполнить команду базы и получить её документы ответа.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Manager::executeCommand(string $db, MongoDB\Driver\Command $command, ?array $options = null): MongoDB\Driver\CursorВыполнить команду базы и получить её документы ответа.
MongoDB\Driver\Manager::executeCommand(string $db, MongoDB\Driver\Command $command, ?array $options = null): MongoDB\Driver\CursorПараметры
| Параметр | Назначение |
|---|---|
| db | Имя базы, без точки и имени коллекции. |
| command | Полный документ команды в объекте Command. |
| options | readConcern, readPreference, session, writeConcern: объекты соответствующих классов. В активной транзакции нельзя задавать индивидуальные read/write concern. |
Возвращаемое значение
Cursor с ответом; для ping — один документ. Для команды с серверным cursor возвращаются его документы.
Ошибки и ограничения
InvalidArgumentException для параметров, ConnectionException для связи, AuthenticationException для входа, RuntimeException для отказа команды. Не считать пустую переменную доказательством успеха.
Версии
С 1.0. Массив options с 1.4; с 2.0 ReadPreference напрямую третьим аргументом не принимается. Общий метод не подставляет concern из URI как специализированные read/write-команды; выбор сервера учитывает readPreference.
Статус службы
$cursor = $manager->executeCommand($database, new MongoDB\Driver\Command(['ping' => 1]));Что получит приложение. ok = 1 позволяет продолжить подготовку импорта.
Исходные данные, полная программа и разбор · Фактический результат
Контроль точной учебной коллекции
$cursor = $manager->executeCommand($database, new MongoDB\Driver\Command([
'listCollections' => 1, 'filter' => ['name' => $collection], 'nameOnly' => true
]));Что получит приложение. До уборки найдена одна собственная коллекция; после finally точный список пуст.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Manager::executeQueryОтправить фильтр коллекции и читать выбранные документы.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query, ?array $options = null): MongoDB\Driver\CursorОтправить фильтр коллекции и читать выбранные документы.
MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query, ?array $options = null): MongoDB\Driver\CursorПараметры
| Параметр | Назначение |
|---|---|
| namespace | Строка база.коллекция, например php_manual_lab.products. |
| query | Query хранит фильтр, projection, sort, limit и другие параметры поиска. |
| options | readPreference или session. readConcern задают в Query; не путайте эти два массива. |
Возвращаемое значение
Cursor. Отсутствие совпадений — корректный пустой результат, а не false.
Ошибки и ограничения
InvalidArgumentException, ConnectionException, AuthenticationException; RuntimeException при ошибке поиска. Ошибки связи возможны и при дальнейших getMore во время обхода.
Версии
С 1.0; options-массив с 1.4, с 2.0 нельзя передавать ReadPreference напрямую. Значения фильтра сравниваются по BSON-правилам, без PHP loose comparison.
Экран двух товаров
$cursor = $manager->executeQuery($namespace, new MongoDB\Driver\Query(
['status' => 'active', 'stock' => ['$gt' => 0]],
['sort' => ['price' => 1, '_id' => 1], 'limit' => 2]
));Что получит приложение. На экран попадают Тарелка и Кружка, а не все четыре документа.
Исходные данные, полная программа и разбор · Фактический результат
Сверить итог импортированной группы
$cursor = $manager->executeQuery($namespace, new MongoDB\Driver\Query(
['group' => 200], ['projection' => ['_id' => 1], 'sort' => ['_id' => 1], 'limit' => 10]
));Что получит приложение. Контрольный ответ содержит 201, 202 и 203: исходный 202 и две новые записи; частичный результат подтверждён документами.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Manager::executeBulkWriteОтправить накопленные изменения и получить подтверждённые счётчики.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $bulk, ?array $options = null): MongoDB\Driver\WriteResultОтправить накопленные изменения и получить подтверждённые счётчики.
MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $bulk, ?array $options = null): MongoDB\Driver\WriteResultПараметры
| Параметр | Назначение |
|---|---|
| namespace | Одна база.коллекция для всех операций пакета. |
| bulk | Непустой ещё не выполненный BulkWrite. |
| options | session и writeConcern. По умолчанию concern берётся из активной транзакции или URI; запись направляется primary. |
Возвращаемое значение
WriteResult. Пакет может разделяться на серверные сообщения; общей атомарности это не добавляет.
Ошибки и ограничения
BulkWriteException содержит ошибки и частичный WriteResult. Возможны ConnectionException/AuthenticationException/RuntimeException; InvalidArgumentException для пустого/повторно выполненного bulk и несовместимых параметров.
Версии
С 1.0; options-массив с 1.4; с 2.0 WriteConcern нельзя передать напрямую третьим аргументом. Для счётчиков нужна подтверждённая запись.
Добавить три товара
$result = $manager->executeBulkWrite($namespace, $bulk);
$inserted = $result->getInsertedCount();Что получит приложение. inserted = 3; последующее чтение сохраняет активные ID 101–103.
Исходные данные, полная программа и разбор · Фактический результат
Принять условное списание
$result = $manager->executeBulkWrite($namespace, $bulk);
$accepted = $result->getMatchedCount() === 1;Что получит приложение. Первое списание принято, второе не выполнено; остаток не стал отрицательным.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Command::__constructОписать команду отдельно от её отправки.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Command::__construct(array|object $document, ?array $commandOptions = null)Описать команду отдельно от её отправки.
MongoDB\Driver\Command::__construct(array|object $document, ?array $commandOptions = null)Параметры
| Параметр | Назначение |
|---|---|
| document | Полный BSON-документ команды: её имя и собственные параметры находятся здесь. |
| commandOptions | Только параметры исполнения курсора: maxAwaitTimeMS (положительные миллисекунды для tailable/getMore), не параметры самой команды. |
Возвращаемое значение
Новый неизменяемый объект Command; сетевого результата ещё нет.
Ошибки и ограничения
InvalidArgumentException при неверных аргументах. Ошибку неизвестной/запрещённой команды получите при executeCommand.
Версии
С 1.0. Второй аргумент и maxAwaitTimeMS добавлены в 1.4. maxTimeMS команды задают в document, а не вторым аргументом.
Описание проверки службы
$command = new MongoDB\Driver\Command(['ping' => 1]);Что получит приложение. После executeCommand получаем ok = 1.
Исходные данные, полная программа и разбор · Фактический результат
Описание проверки коллекции
$command = new MongoDB\Driver\Command(['listCollections' => 1,
'filter' => ['name' => $collection], 'nameOnly' => true]);Что получит приложение. Команда возвращает только совпадение точного имени, не раскрывает весь перечень коллекций.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Query::__constructСобрать фильтр и серверные ограничения выдачи.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Query::__construct(array|object $filter, ?array $queryOptions = null)Собрать фильтр и серверные ограничения выдачи.
MongoDB\Driver\Query::__construct(array|object $filter, ?array $queryOptions = null)Параметры
| Параметр | Назначение |
|---|---|
| filter | Предикат; [] совпадает со всеми. Типы BSON важны. |
| projection / sort | array|object: поля ответа / порядок; уникальный последний ключ стабилизирует порядок. |
| limit / skip / batchSize | int: предел (0 означает без предела), пропуск, размер порции. batchSize не заменяет limit. |
| maxTimeMS / maxAwaitTimeMS | int: серверная обработка / ожидание tailable getMore. |
| collation / hint / min / max | Правила строк; индекс; включённая нижняя / исключённая верхняя граница индекса. |
| readConcern / comment / let | ReadConcern; метка трассировки; константные выражения (let: сервер 5.0+). |
| allowDiskUse / allowPartialResults | bool: дисковая сортировка / неполный ответ при недоступности shard. |
| tailable / awaitData / noCursorTimeout | bool: специальный продолжающийся курсор и его ожидание/простой. |
| returnKey / showRecordId / singleBatch | bool: ключи индекса, внутренний ID, закрытие после порции. |
| exhaust / explain | Исторические OP_QUERY-параметры; для современного explain используйте команду explain. |
Возвращаемое значение
Неизменяемый Query, выполняемый через executeQuery. Никаких документов конструктор не возвращает.
Ошибки и ограничения
InvalidArgumentException при неверных аргументах. Серверные ограничения опций проверяются при исполнении.
Версии
С 1.0. 1.8: allowDiskUse; 1.14: let и произвольный BSON comment; 2.0: удалены partial/maxScan/modifiers/oplogReplay/snapshot. Отрицательный limit больше не включает singleBatch.
Страница каталога
$query = new MongoDB\Driver\Query(['stock' => ['$gt' => 0], 'status' => 'active'],
['projection' => ['title' => 1, 'price' => 1], 'sort' => ['price' => 1, '_id' => 1], 'limit' => 2]);Что получит приложение. Переданы только нужные поля и два подходящих товара.
Исходные данные, полная программа и разбор · Фактический результат
Карточка и строгий тип ID
$query = new MongoDB\Driver\Query(['_id' => 101], ['limit' => 1]);
$wrongType = new MongoDB\Driver\Query(['_id' => '101'], ['limit' => 1]);Что получит приложение. Число находит Кружку, строка даёт пустую выборку; тип входного ID нужно проверять.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\BulkWrite::__constructСоздать очередь операций с определённой политикой ошибок.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\BulkWrite::__construct(?array $options = null)Создать очередь операций с определённой политикой ошибок.
MongoDB\Driver\BulkWrite::__construct(?array $options = null)Параметры
| Параметр | Назначение |
|---|---|
| ordered | bool, по умолчанию true: последовательность и остановка после ошибки; false: независимый порядок и продолжение. |
| bypassDocumentValidation | bool, false: обход validation только при явном включении и правах, сервер 3.2+. |
| comment | Произвольный BSON-комментарий, сервер 4.4+. |
| let | array|object константных выражений, сервер 5.0+. Используется как $$имя в выражениях. |
Возвращаемое значение
Изменяемый объект очереди: добавляйте insert/update/delete. Создание ничего не записывает.
Ошибки и ограничения
InvalidArgumentException при параметрах. Серверные ошибки возникают при executeBulkWrite, включая несовместимые серверные версии опций.
Версии
С 1.0; bypassDocumentValidation с 1.1; comment/let с 1.14. ordered=false не делает операции транзакцией.
Остановиться после первого конфликта
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => true]);
// ID 102 уже существует; операции: 101, 102, 103.Что получит приложение. Добавлен 101, исходный 102 сохранён; 103 не был вставлен после duplicate key.
Исходные данные, полная программа и разбор · Фактический результат
Сохранить независимый хвост импорта
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
// ID 202 уже существует; операции: 201, 202, 203.Что получит приложение. Добавлены 201 и 203, исходный 202 сохранён; ошибка второй операции всё равно возвращена.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\BulkWrite::insertДобавить документ в очередь и получить его будущий ID.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\BulkWrite::insert(array|object $document): mixedДобавить документ в очередь и получить его будущий ID.
MongoDB\Driver\BulkWrite::insert(array|object $document): mixedПараметры
| Параметр | Назначение |
|---|---|
| document | Документ для вставки. Без _id драйвер генерирует MongoDB\BSON\ObjectId; явный _id сохраняет свой BSON-тип. |
Возвращаемое значение
Значение _id, в том числе сгенерированный ObjectId. Это результат подготовки, ещё не подтверждение записи.
Ошибки и ограничения
InvalidArgumentException при неверном документе/аргументах. Duplicate key возникает при исполнении; не ловите его только вокруг insert.
Версии
С 1.0. С 1.3 возвращается также явно заданный _id; раньше значение возвращалось только для сгенерированного ObjectId.
Импорт товара с внешним идентификатором
$id = $bulk->insert(['_id' => 101, 'title' => 'Кружка', 'status' => 'active']);Что получит приложение. id = 101; серверный getInsertedCount после всего каталога равен 3.
Исходные данные, полная программа и разбор · Фактический результат
Изолировать временные макеты
$drafts->insert(['_id' => 201, 'title' => 'Устаревший макет', 'status' => 'draft']);Что получит приложение. Черновик отличим по status, поэтому позднее удаляется без затрагивания опубликованного товара.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\BulkWrite::updateДобавить изменение выбранных документов без неявного создания товара.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\BulkWrite::update(array|object $filter, array|object $newObj, ?array $updateOptions = null): voidДобавить изменение выбранных документов без неявного создания товара.
MongoDB\Driver\BulkWrite::update(array|object $filter, array|object $newObj, ?array $updateOptions = null): voidПараметры
| Параметр | Назначение |
|---|---|
| filter | Правила отбора; [] совпадает со всеми документами. |
| newObj | Операторы ($set/$inc), документ замены либо aggregation pipeline. |
| multi / upsert | bool, оба false: изменить один / создать при отсутствии. multi нельзя true при замене. |
| arrayFilters / collation / hint | Фильтры элементов массива, сравнение строк, выбранный индекс. |
| sort | Порядок выбора единственного документа; нельзя с multi=true. |
Возвращаемое значение
void: операция подготовлена; matched/modified будут в WriteResult исполнения.
Ошибки и ограничения
InvalidArgumentException при аргументах; ошибки схемы, типов, уникальности и версии сервера проявляются при executeBulkWrite.
Версии
С 1.0. collation 1.2/сервер 3.4; arrayFilters 1.4/3.6 (строгая ошибка поддержки с 1.5); pipeline 1.6/4.2; hint 1.7/4.2; sort 1.21/8.0.
Изменить одну цену
$bulk->update(['_id' => 101], ['$set' => ['price' => 650]], ['multi' => false, 'upsert' => false]);Что получит приложение. Цена 650 сохранена, title/status остаются прежними.
Исходные данные, полная программа и разбор · Фактический результат
Проверить и уменьшить остаток
$bulk->update(['_id' => 101, 'stock' => ['$gte' => 2]], ['$inc' => ['stock' => -2]], ['upsert' => false]);Что получит приложение. При stock = 3 остаётся 1; следующий запрос 2 единиц не выполняется.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\BulkWrite::deleteПодготовить ограниченное удаление выбранного документа или группы.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\BulkWrite::delete(array|object $filter, ?array $deleteOptions = null): voidПодготовить ограниченное удаление выбранного документа или группы.
MongoDB\Driver\BulkWrite::delete(array|object $filter, ?array $deleteOptions = null): voidПараметры
| Параметр | Назначение |
|---|---|
| filter | Точное условие; пустой массив совпадёт со всей коллекцией. |
| limit | bool: true — один, false (по умолчанию) — все совпавшие. Не произвольное количество. |
| collation | array|object правила строк, locale обязателен; сервер 3.4+. |
| hint | Имя/описание индекса; сервер 4.4+. |
Возвращаемое значение
void: ничего ещё не удалено; число подтверждает getDeletedCount после исполнения.
Ошибки и ограничения
InvalidArgumentException при аргументах; серверный отказ возникает при executeBulkWrite. По неуникальному фильтру limit=true не задаёт, какой документ будет первым.
Версии
С 1.0. collation добавлена в 1.2, hint в 1.8. Используйте BSON-тип ID, соответствующий сохранённому.
Удалить устаревший выбранный макет
$one->delete(['_id' => 201, 'status' => 'draft'], ['limit' => true]);Что получит приложение. Удалён ровно 1 документ с проверенным ID и статусом.
Исходные данные, полная программа и разбор · Фактический результат
Очистить оставшиеся черновики
$remainingDrafts->delete(['status' => 'draft'], ['limit' => false]);Что получит приложение. Удалены ещё 2 черновика; активные ID 101–103 сохранены.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Cursor::setTypeMapПолучать BSON-документы в нужной PHP-форме без JSON-перекодирования.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Cursor::setTypeMap(array $typemap): voidПолучать BSON-документы в нужной PHP-форме без JSON-перекодирования.
MongoDB\Driver\Cursor::setTypeMap(array $typemap): voidПараметры
| Параметр | Назначение |
|---|---|
| typemap | root — корневой документ, document — вложенные документы, array — BSON-массивы; значения array/object или подходящий класс. fieldPaths уточняет отдельные пути. |
Возвращаемое значение
void; меняется декодирование этого курсора. Данные коллекции и специальные BSON-значения не переписываются.
Ошибки и ограничения
InvalidArgumentException для параметров; при обходе — если заданный класс нельзя создать или он не реализует BSON\Unserializable. Установите карту до чтения.
Версии
Метод с mongodb 1.0. Правила Persistable/__pclass и вложенных путей описаны в официальном разделе сериализации; эта глава использует обычные массивы и stdClass.
Строки для PHP-шаблона
$cursor->setTypeMap(['root' => 'array']);
foreach ($cursor as $product) { echo $product['title']; }Что получит приложение. Вместо $product->title читается $product["title"]; Тарелка и Кружка не меняются.
Исходные данные, полная программа и разбор · Фактический результат
Вложенные габариты товара
$arrayCursor->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
$product = $arrayCursor->toArray()[0];Что получит приложение. dimensions — массив, $product["dimensions"]["width"] равно 8.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\Cursor::toArrayСобрать небольшой ответ курсора в PHP-массив для дальнейшего обращения.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\Cursor::toArray(): arrayСобрать небольшой ответ курсора в PHP-массив для дальнейшего обращения.
MongoDB\Driver\Cursor::toArray(): arrayПараметры
Параметров нет. Метод вызывается у результата уже выполненной операции.
Возвращаемое значение
Массив документов текущего результата, декодированных по type map. Пустой ответ — []. Документы по умолчанию остаются объектами.
Ошибки и ограничения
InvalidArgumentException при неверных аргументах; обход может получить сетевой/серверный отказ или ошибку type map. Продвинутый курсор нельзя считать произвольно перематываемым.
Версии
С mongodb 1.0. Метод расходует память на весь ответ. Для больших выдач сначала ограничьте серверный Query или обрабатывайте курсор последовательно.
Разобрать один ответ ping
$reply = $manager->executeCommand($database, new MongoDB\Driver\Command(['ping' => 1]))->toArray();
echo (int) $reply[0]->ok;Что получит приложение. Один документ даёт ok = 1; такой ответ обоснованно собран целиком.
Исходные данные, полная программа и разбор · Фактический результат
Получить карточку по ID
$arrayCursor->setTypeMap(['root' => 'array', 'document' => 'array']);
$product = $arrayCursor->toArray()[0]; // Query заранее имеет limit = 1Что получит приложение. Ограниченная карточка содержит Кружку и вложенную ширину 8; не загружается весь каталог.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\WriteResult::getInsertedCountУзнать число подтверждённых insert в выполненном пакете.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\WriteResult::getInsertedCount(): intУзнать число подтверждённых insert в выполненном пакете.
MongoDB\Driver\WriteResult::getInsertedCount(): intПараметры
Параметров нет. Метод вызывается у результата уже выполненной операции.
Возвращаемое значение
Число вставленных документов, без upsert. Это итог пакета, не идентификатор и не count всей коллекции.
Ошибки и ограничения
LogicException для неподтверждённой записи; InvalidArgumentException при неверных аргументах. w=0 не означает ноль изменённых документов: результат неизвестен.
Версии
С mongodb 1.0. В 2.0 для unacknowledged write возвращение null заменено исключением; используйте подтверждённую запись и при необходимости isAcknowledged().
Подтвердить импорт каталога
$inserted = $catalog->getInsertedCount();Что получит приложение. 3 товара подтверждены сервером; можно показать счётчик обработанной порции.
Исходные данные, полная программа и разбор · Фактический результат
Учесть успех до/после ошибки
$inserted = $error->getWriteResult()->getInsertedCount();Что получит приложение. ordered=true: 1; ordered=false: 2. Нельзя считать исключение откатом всей группы.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\WriteResult::getMatchedCountОтделить найденный документ от фактически изменённого.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\WriteResult::getMatchedCount(): intОтделить найденный документ от фактически изменённого.
MongoDB\Driver\WriteResult::getMatchedCount(): intПараметры
Параметров нет. Метод вызывается у результата уже выполненной операции.
Возвращаемое значение
Число документов, выбранных update. Может превышать modified, если присваивается прежнее значение.
Ошибки и ограничения
LogicException для неподтверждённой записи; InvalidArgumentException при неверных аргументах. w=0 не означает ноль изменённых документов: результат неизвестен.
Версии
С mongodb 1.0. В 2.0 для unacknowledged write возвращение null заменено исключением; используйте подтверждённую запись и при необходимости isAcknowledged().
Понять повторное сохранение формы
$matched = $result->getMatchedCount();Что получит приложение. При второй цене 650 matched = 1: товар существует, хотя modified = 0.
Исходные данные, полная программа и разбор · Фактический результат
Принять условную операцию
$accepted = $result->getMatchedCount() === 1;Что получит приложение. Первая заявка соответствует условию, вторая — нет; бизнес-ответ различается без загрузки всего склада.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\WriteResult::getModifiedCountПосчитать документы, в которых действительно изменились значения.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\WriteResult::getModifiedCount(): intПосчитать документы, в которых действительно изменились значения.
MongoDB\Driver\WriteResult::getModifiedCount(): intПараметры
Параметров нет. Метод вызывается у результата уже выполненной операции.
Возвращаемое значение
Число изменённых существующих документов. При записи прежнего значения меньше matched; не число полей.
Ошибки и ограничения
LogicException для неподтверждённой записи; InvalidArgumentException при неверных аргументах. w=0 не означает ноль изменённых документов: результат неизвестен.
Версии
С mongodb 1.0. В 2.0 для unacknowledged write возвращение null заменено исключением; используйте подтверждённую запись и при необходимости isAcknowledged().
Не выдавать повтор за новую правку
$modified = $result->getModifiedCount();Что получит приложение. Смена цены даёт 1, повтор той же цены — 0, отсутствующий товар — 0 вместе с matched=0.
Исходные данные, полная программа и разбор · Фактический результат
Проверить фактическое списание
$modified = $result->getModifiedCount();Что получит приложение. Первый $inc изменил один документ, второй — ни одного; итоговый остаток 1.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
MongoDB\Driver\WriteResult::getDeletedCountПодтвердить количество удалённых документов, не предполагая его заранее.
mongodb 1.0+; примеры mongodb 2.5+ · mongodb
MongoDB\Driver\WriteResult::getDeletedCount(): intПодтвердить количество удалённых документов, не предполагая его заранее.
MongoDB\Driver\WriteResult::getDeletedCount(): intПараметры
Параметров нет. Метод вызывается у результата уже выполненной операции.
Возвращаемое значение
Количество документов, удалённых выполненным пакетом. Ноль — корректный ответ при отсутствии совпадения.
Ошибки и ограничения
LogicException для неподтверждённой записи; InvalidArgumentException при неверных аргументах. w=0 не означает ноль изменённых документов: результат неизвестен.
Версии
С mongodb 1.0. В 2.0 для unacknowledged write возвращение null заменено исключением; используйте подтверждённую запись и при необходимости isAcknowledged().
Отчёт об удалении одной карточки
$deleted = $oneResult->getDeletedCount();Что получит приложение. 1 — выбранный ID 201 удалён; нельзя использовать void-результат delete как подтверждение.
Исходные данные, полная программа и разбор · Фактический результат
Отчёт об очистке группы
$deleted = $manyResult->getDeletedCount();Что получит приложение. 2 — удалены оставшиеся draft. Проверочное чтение доказывает сохранность трёх active.
Исходные данные, полная программа и разбор · Фактический результат
Фрагменты используют переменные полного сценария: $manager — драйвер, $database — имя базы, $namespace — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.
Источники и обсуждения
- MongoDB\Driver\Manager::__construct
- MongoDB\Driver\Manager::executeCommand
- MongoDB\Driver\Manager::executeQuery
- MongoDB\Driver\Manager::executeBulkWrite
- MongoDB\Driver\Command::__construct
- MongoDB\Driver\Query::__construct
- MongoDB\Driver\BulkWrite::__construct
- MongoDB\Driver\BulkWrite::insert
- MongoDB\Driver\BulkWrite::update
- MongoDB\Driver\BulkWrite::delete
- MongoDB\Driver\Cursor::setTypeMap
- MongoDB\Driver\Cursor::toArray
- MongoDB\Driver\WriteResult::getInsertedCount
- MongoDB\Driver\WriteResult::getMatchedCount
- MongoDB\Driver\WriteResult::getModifiedCount
- MongoDB\Driver\WriteResult::getDeletedCount
- PHP: BSON и PHP, карты типов
- MongoDB: атомарность записи
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


