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

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

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

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

Глава 143 · После первого каталога MongoDB, массивов и объектов

MongoDB: запросы, курсоры и управляемая запись через PHP-драйвер

Реальный ping, серверная выборка, типы курсора, insert/delete, matched/modified, условный остаток и частичный импорт.

Команда, очередь, курсор и результат записи

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

Если MongoDB встречается впервые, начните с документа, коллекции, BSON и первого каталога. Здесь уже нужны массивы, вызов функций и объекты. new создаёт объект; стрелка → в схемах показывает движение данных, а -> в PHP вызывает метод объекта. В коде MongoDB\Driver\Query — полное имя класса: обратные слеши разделяют пространство имён.

Как товар доходит до экрана
  1. PHP-массив описывает условие и поля
  2. Query хранит описание
  3. Manager отправляет запрос MongoDB
  4. Сервер возвращает выбранные BSON-документы
  5. Cursor декодирует их в PHP
  6. 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.

Что происходит
  1. Manager хранит адрес и параметры
  2. Command содержит ping = 1
  3. executeCommand обращается к серверу
  4. Cursor отдаёт документ ok = 1
  5. Другой локальный порт не отвечает как MongoDB → ConnectionException

Самая короткая полезная операция

$command = new MongoDB\Driver\Command(['ping' => 1]);
$cursor = $manager->executeCommand($database, $command);
$reply = $cursor->toArray();
echo (int) $reply[0]->ok; // 1

Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.

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

ПроверкаРезультат
pingok = 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.

Что происходит
  1. status = active и stock > 0
  2. projection оставляет ID, title, price
  3. sort: price, затем уникальный _id
  4. limit = 2
  5. 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-результатаСамостоятельный пример
<?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.

Что происходит
  1. insert добавляет инструкции в BulkWrite
  2. executeBulkWrite выполняет пакет
  3. WriteResult сообщает inserted = 3
  4. delete с limit = true удаляет ID 201
  5. delete с limit = false удаляет два оставшихся draft
  6. Чтение подтверждает 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.

Что происходит
  1. Фильтр ищет _id
  2. Оператор $set меняет только price
  3. matched считает совпавшие документы
  4. modified считает фактически изменённые
  5. Контрольное чтение: 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: цена изменилась

Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.

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

Действиеmatchedmodified
Изменить цену11
Повторить ту же цену10
Изменить отсутствующий товар00

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

$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 единицы; количество заранее является проверенным положительным целым.

Что происходит
  1. Фильтр: _id 101 и stock ≥ 2
  2. Оператор $inc прибавляет -2
  3. Первый запрос: 3 → 1
  4. Второй: 1 не удовлетворяет ≥ 2
  5. matched 0, остаток остаётся 1

Самая короткая полезная операция

$quantity = 2;
$bulk->update(
    ['_id' => 101, 'stock' => ['$gte' => $quantity]],
    ['$inc' => ['stock' => -$quantity]],
    ['multi' => false, 'upsert' => false]
); // проверка и изменение одного документа — одна операция

Этот фрагмент использует подготовленные в полном примере переменные и документы. Он выделяет текущий механизм; самостоятельный архив ниже содержит все необходимые файлы.

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

ЗапросКоличествоmatchedmodifiedОсталосьРешение
Попытка 12111принято
Попытка 22001не выполнено

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

$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 при любом порядке исполнения.

Что происходит
  1. Первая запись успешна
  2. Вторая получает duplicate key 11000
  3. ordered = true останавливает хвост
  4. ordered = false продолжает независимые операции
  5. Из исключения читаем частичный WriteResult
  6. 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 = true1100011101, 102
ordered = false1100012201, 202, 203

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

ordered = true сохраняет порядок и прекращает дальнейшие операции при ошибке записи. false разрешает продолжать; ошибка всё равно сообщается. Индекс операции начинается с нуля: 1 — второй insert. catch в полной программе проверяет ожидаемые код, индекс и отсутствие write concern error; другие отказы пробрасываются. getInsertedCount берётся из getWriteResult исключения, поэтому мы не теряем подтверждённый частичный успех. Проверка документов отдельно подтверждает число. Этот BulkWrite после попытки не запускают снова.

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

BulkWrite сам по себе не транзакция. ordered = false не гарантирует исходный порядок или универсальную параллельность. Если операции зависят друг от друга, менять ordered ради скорости нельзя. Потеря соединения может оставить неопределённость результата; это другая ситуация, чем полученный серверный duplicate key. Для возобновления импорта нужны стабильные идентификаторы и журнал обработки.

Полная самостоятельная программа и архив
Увидеть частичный результат пакета при конфликте IDСамостоятельный пример
<?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ТипСмысл / ограничения
appnamestringИмя приложения в диагностике; до 128 символов.
authMechanism / authMechanismPropertiesstring / arrayМеханизм и его строковые свойства.
authSourcestringБаза учётной записи; выше defaultAuthDb, иначе admin. Для внешнего хранилища — $external.
username / passwordstringУчётные данные отдельно от URL-кодирования URI.
compressors / zlibCompressionLevelstring / intПриоритет компрессоров через запятую; уровень действует только для zlib.
connectTimeoutMS / socketTimeoutMSintСоединение / обмен сокета, миллисекунды; значения по умолчанию 10000 / 300000.
serverSelectionTimeoutMS / serverSelectionTryOnceint / boolВыбор сервера: 30000 мс; одна попытка сканирования по умолчанию true.
heartbeatFrequencyMS / socketCheckIntervalMSintПроверка топологии: 60000 мс (минимум 500); проверка простаивавшего сокета: 5000 мс.
directConnection / replicaSetbool / stringПрямой адрес либо обнаружение участников указанного replica set.
loadBalancedboolБалансировщик: один host, без replicaSet и directConnection=true; по умолчанию false.
localThresholdMSintОкно выбора по задержке, 15 мс.
maxStalenessSecondsintПредел отставания secondary; если задан — int32, минимум 90 секунд.
readPreference / readPreferenceTagsstring / arrayРежим чтения (primary) и наборы тегов.
readConcernLevelstringУровень изоляции чтения.
w / wTimeoutMS / journalint|string / int|string / boolПодтверждение записи, его таймаут (неотрицательный int32), требование журнала.
retryReads / retryWritesboolПовтор некоторых временных отказов; оба true по умолчанию, зависят от топологии/операции.
enableOverloadRetargeting / maxAdaptiveRetriesbool / intПовторный выбор сервера при SystemOverloadedError; false / положительное число, default 2.
srvMaxHosts / srvServiceNameint / stringПредел SRV-узлов (0 без ограничения), сервис mongodb.
tlsboolTLS, по умолчанию false; другие TLS-опции могут включить его автоматически.
tlsCAFile / tlsCertificateKeyFile / tlsCertificateKeyFilePasswordstringCA, клиентский сертификат/ключ (при необходимости объединённый файл), пароль ключа.
tlsAllowInvalidCertificates / tlsAllowInvalidHostnames / tlsInsecureboolОслабляют проверку; false. tlsInsecure объединяет две первые уступки; не применять для рабочего сервера.
tlsDisableCertificateRevocationCheck / tlsDisableOCSPEndpointCheckboolОтключают отзыв сертификата / запрос OCSP; false.
driverOptionsТипСмысл
ca_dir / crl_filestringХешированный каталог CA / файл списка отзыва.
disableClientPersistenceboolfalse; true создаёт отдельный непостоянный libmongoc client и закрывает его с Manager. Обычно не требуется.
driverarrayМетаданные name/version/platform верхней библиотеки; handshake ограничен 512 байтами.
serverApiMongoDB\Driver\ServerApiВыбор стабильной серверной API-версии; без опции не объявлена.
autoEncryptionarrayНастройки ниже; шифрование не включается нашими учебными программами.
autoEncryption / вложенные поляТипСмысл
keyVaultClient / keyVaultNamespaceManager / stringОтдельный клиент (иначе текущий) / обязательная база.коллекция ключей.
kmsProvidersarrayХотя бы один провайдер: aws, azure, gcp, kmip, local.
awsarrayaccessKeyId, secretAccessKey; необязательный sessionToken.
azurearraytenantId, clientId, clientSecret; identityPlatformEndpoint по умолчанию login.microsoftonline.com.
gcparrayemail, privateKey (base64|BSON Binary); endpoint по умолчанию oauth2.googleapis.com.
kmip / localarrayendpoint / key (мастер-ключ 96 байт, base64|BSON Binary).
tlsOptionsarrayПо KMS-провайдеру: tlsCaFile, tlsCertificateKeyFile, tlsCertificateKeyFilePassword, tlsDisableOCSPEndpointCheck.
schemaMap / encryptedFieldsMaparray|objectСхемы по namespace; одна коллекция не может быть в обеих картах. Локальная карта исключает доверие подменённой серверной схеме.
bypassAutoEncryption / bypassQueryAnalysisboolfalse; отключение автоматического шифрования / анализа команды. Автодешифрование возможно и при bypassAutoEncryption.
extraOptionsarrayУправление mongocryptd и crypt_shared — перечислено ниже.
mongocryptdURI / mongocryptdBypassSpawnstring / boolmongodb://localhost:27020 / false; адрес процесса / запрет его запуска.
mongocryptdSpawnPath / mongocryptdSpawnArgsstring / arrayПуть (иначе системный) / аргументы (default --idleShutdownTimeoutSecs=60).
cryptSharedLibPath / cryptSharedLibRequiredstring / boolПуть библиотеки / обязательность загрузки (false).

Пустой документ aws/azure/gcp включает получение автоматических учётных данных при поддерживаемой конфигурации. Автоматическое шифрование применяется к коллекциям, требует listCollections и дополнительных компонентов; команды базы/представления имеют ограничения. Локальная schemaMap описывает шифрование, а не произвольную серверную валидацию. Явное шифрование/дешифрование и автоматическое дешифрование доступны отдельно от enterprise-автошифрования. Эти режимы здесь справочно перечислены, но не установлены и не проверены примерами.

URI может содержать несколько узлов replica set, mongos, Unix-сокет (путь кодируют rawurlencode) и authSource. Учётные компоненты URI кодируют отдельно; база в пути при отсутствии учётной записи сама по себе не выбирает рабочую коллекцию. Учебный helper сознательно разрешает только loopback; это не ограничение Manager.

Версия mongodbИзменения конструктора
1.1 / 1.2URI стал необязательным; затем default 127.0.0.1, appname/TLS-параметры, отказ от PHP Streams; connectTimeoutMS 10 секунд.
1.3 / 1.4 / 1.5authMechanism(Properties) в uriOptions; компрессия/retryWrites; wTimeoutMS всегда проверяется.
1.6 / 1.7retryReads и современные TLS URI-поля; autoEncryption и автоматическое включение TLS соответствующими опциями.
1.8 / 1.10directConnection, проверки отзыва, driver; затем disableClientPersistence, Azure/GCP, base64-ключи.
1.11 / 1.12 / 1.13loadBalanced; KMIP и KMS TLS; SRV-ограничения.
1.14 / 1.15 / 1.16queryable encryption/crypt_shared; автоматические AWS credentials; sessionToken, Azure/GCP credentials, OCSP для KMS.
2.0canonicalizeHostname → 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.
optionsreadConcern, 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.
queryQuery хранит фильтр, projection, sort, limit и другие параметры поиска.
optionsreadPreference или 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.
optionssession и 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 / sortarray|object: поля ответа / порядок; уникальный последний ключ стабилизирует порядок.
limit / skip / batchSizeint: предел (0 означает без предела), пропуск, размер порции. batchSize не заменяет limit.
maxTimeMS / maxAwaitTimeMSint: серверная обработка / ожидание tailable getMore.
collation / hint / min / maxПравила строк; индекс; включённая нижняя / исключённая верхняя граница индекса.
readConcern / comment / letReadConcern; метка трассировки; константные выражения (let: сервер 5.0+).
allowDiskUse / allowPartialResultsbool: дисковая сортировка / неполный ответ при недоступности shard.
tailable / awaitData / noCursorTimeoutbool: специальный продолжающийся курсор и его ожидание/простой.
returnKey / showRecordId / singleBatchbool: ключи индекса, внутренний 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)

Параметры

ПараметрНазначение
orderedbool, по умолчанию true: последовательность и остановка после ошибки; false: независимый порядок и продолжение.
bypassDocumentValidationbool, false: обход validation только при явном включении и правах, сервер 3.2+.
commentПроизвольный BSON-комментарий, сервер 4.4+.
letarray|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 / upsertbool, оба 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Точное условие; пустой массив совпадёт со всей коллекцией.
limitbool: true — один, false (по умолчанию) — все совпавшие. Не произвольное количество.
collationarray|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

Параметры

ПараметрНазначение
typemaproot — корневой документ, 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 — база.коллекция. Это выделенные операции из шести самостоятельных программ, а не отдельные программы без подключения и данных.

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

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

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

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

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