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

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

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

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

Глава 121 · После массивов, объектов, исключений и первой базы данных

MySQL Document Store: подключение, коллекция и первый каталог

От первого ответа X Protocol до каталога документов: создание коллекции, настоящий readback, серверные ID, связанные параметры и страницы результата.

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

У лампы есть яркость и варианты питания, у кабеля — длина и разъёмы. Вы хотите сохранить разные свойства товаров и показать посетителю короткий каталог. Здесь данные хранятся как JSON-документы в коллекции MySQL Document Store. Расширение mysql_xdevapi предоставляет операции создания, чтения, изменения и удаления (CRUD) через X DevAPI и X Protocol; этот API также умеет работать с реляционными таблицами.

Одна лампа проходит путь от программы к каталогу
  1. PHP-массив: _id=LAMP-1, price=1200, options=[настольная,USB]
  2. Session: установленное соединение X Protocol с локальным MySQL
  3. Schema php_manual_x139: выделенная учебная база
  4. Collection mysql139_one_…: документы каталога
  5. add -> execute -> Result: подтверждение записи
  6. getOne(LAMP-1): сохранённые поля для карточки

Коллекцию можно представить как папку карточек, а _id — как уникальную подпись карточки. Но это лишь модель: документы хранятся сервером и участвуют в запросах/транзакциях, а не являются отдельными файлами на вашем компьютере. Session, Schema и Collection — PHP-объекты доступа; сам документ в первом примере — массив данных. Schema означает базу MySQL, а PHP namespace mysql_xdevapi группирует имена функций и классов языка.

Минимальная запись подключения выглядит так:

$session = mysql_xdevapi\getSession($uri);

$uri содержит строку адреса и настроек. Функция получает её в круглых скобках, знак = сохраняет возвращённую Session в переменную $session, а ; завершает инструкцию. Дальше $session->getSchema($name) вызывает метод объекта с именем базы. Наличие объекта ещё не означает выполнение всех будущих действий: createCollection создаёт хранилище, а getCollection получает объект доступа. В первой полной программе ниже URI обязательно приходит из проверенного окружения.

Нужные основы: массив и его поля, аргумент и возвращаемое значение, объект и метод, пространство имён PHP, завершение работы в finally. Текущие понятия разобраны здесь; ссылки помогают вернуться к синтаксису языка.

Если задача уже построена вокруг SQL-таблиц, MySQLi или PDO_MYSQL остаются отдельными вариантами; сравнение находится в выборе MySQL API. Колонка JSON с SQL-функциями описана в уроке SQL JSON. X DevAPI выбирают ради этого конкретного API коллекций и работы через X Protocol; сам факт другого API не доказывает ускорение приложения.

Полная карта первого уровня официальной ветви

НаправлениеКуда перейти
Установка и общие сведенияУстановка/настройка · Константы · Изменения версий · Первый маршрут · Функции expression/getSession
Сеанс и объекты базыClient · Session · Schema · Collection · Table
Документные и табличные операцииCollectionAdd · CollectionFind · CollectionModify · CollectionRemove · TableDelete · TableInsert · TableSelect · TableUpdate · SqlStatement · Statement · Expression
Результаты и сведенияResult · DocResult · RowResult · SqlStatementResult · ColumnResult · FieldMetadata · ExecutionStatus · Warning · Exception · Driver
Контракты интерфейсовBaseResult · CrudOperationBindable · CrudOperationLimitable · CrudOperationSkippable · CrudOperationSortable · DatabaseObject · SchemaObject · Executable

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

Какие компоненты нужны по обе стороны соединения

Чтобы открыть каталог, нужны две стороны: PHP с отдельным расширением mysql_xdevapi и MySQL8+ с включённым X Plugin. Модуль не входит в стандартный набор PHP. Серверный плагин и клиентская DLL — разные компоненты: существование одного не доказывает работоспособность другого.

КомпонентЧто проверить
PHPИменно тот исполняемый файл, которым запускается пример, должен загрузить совместимый mysql_xdevapi. TS/NTS, архитектура и ветка PHP должны соответствовать бинарному модулю.
MySQLНужен MySQL8+ и X Plugin; в стандартной конфигурации MySQL он включён, но конкретная сборка/настройка может его отключить. X Protocol имеет свой порт; обычный SQL-порт не заменяет его.
Сборка из исходниковPHP Manual перечисляет Boost1.53.0 или новее, OpenSSL и Protobuf. Это библиотеки для компиляции, а не PHP-библиотеки Composer. Подробности инструментов сборки находятся в официальном разделе сборки.
Версии учебного окруженияPHP8.3.35 NTSx64, mysql_xdevapi8.0.30 и MySQL8.4.13; X Protocol работает на127.0.0.1:33140 с TLSv1.3. Точные версии своего процесса можно найти в result.json.

В Windows-каталоге PECL для8.0.30 опубликованы варианты DLL, в том числе для PHP8.3. Дата выпуска расширения и наличие архивов не доказывают совместимость с любой будущей веткой PHP. Поэтому в этой лаборатории выбран отдельный runtime; текущий PHP8.5 основного руководства не подменяется незаметно.

Проверки дают разные ответы
  1. extension_loaded: модуль загружен этим PHP
  2. getSession: установился X-сеанс с настроенным сервером
  3. getServerVersion: получен ответ этого сервера
  4. existsInDatabase: доступна выбранная учебная схема
  5. add/execute/getOne: запись действительно прошла и прочитана

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

Установка расширения и включение его в конкретный PHP — два отдельных шага. На Windows сначала выбирают совместимую DLL и её зависимости, затем подключают её в php.ini выбранного runtime. В профиле139 OpenSSL загружается перед mysql_xdevapi. Не копируйте бинарник от другой ветки PHP и не считайте composer require установкой системного модуля.

php --ini
php -v
php -m
php --ri mysql_xdevapi

Это команды терминала для осмотра выбранного PHP: --ini показывает конфигурацию, -v версию, -m список модулей, --ri сведения расширения. Они не создают базу и не проверяют X-сеанс. Если в системе несколько PHP, используйте полный путь к нужному exe и его ini. Параметры и исходники выпусков публикуются в карточке PECL. Общий механизм описан в установке PECL-расширений.

Старый пример установки из официальной страницы

PHP Manual приводит конкретный исторический контекст Ubuntu18.04 и PHP7.2. Сохраняем его смысл полностью: сначала инструменты и зависимости, затем пакет разработки PHP и компиляция расширения. Это справочная запись для той среды, не команда подготовки нынешнего Windows-стенда.

apt install build-essential libprotobuf-dev libboost-dev openssl protobuf-compiler liblz4-tool zstd
apt install php7.2-cli php7.2-dev php7.2-mysql php7.2-pdo php7.2-xml
pecl install mysql_xdevapi

pecl install по умолчанию не включает модуль. В том Debian/Ubuntu-примере создаётся ini, затем используется phpenmod либо ручная символическая ссылка в CLI conf.d:

echo "extension=mysql_xdevapi.so" > /etc/php/7.2/mods-available/mysql_xdevapi.ini
phpenmod -v 7.2 -s ALL mysql_xdevapi
# Альтернативный способ вместо phpenmod:
ln -s /etc/php/7.2/mods-available/mysql_xdevapi.ini /etc/php/7.2/cli/conf.d/20-mysql_xdevapi.ini
php -m | grep mysql

Наличие mysql_xdevapi, mysqli, mysqlnd и pdo_mysql в списке означает загрузку соответствующих компонентов. Имена не взаимозаменяемы: каждый API используется своим кодом. Для новой Linux-среды выбирают её актуальные пакеты и путь ini, сохраняя разделение установки/включения/проверки.

Запуск именно этой лаборатории

Администратор отдельного учебного MySQL один раз создаёт базу и учётную запись ниже через свой SQL-клиент. В нашем профиле административное соединение использует classic-порт33139. CREATE DATABASE создаёт базу, CREATE USER — пользователя только с loopback-адреса, REQUIRE SSL требует шифрование. GRANT выдаёт перечисленные права лишь внутри учебной схемы: чтение, изменение документов и создание/удаление собственных коллекций. Это административная подготовка, не код example.php.

SELECT @@GLOBAL.partial_revokes;

CREATE DATABASE `php_manual_x139` CHARACTER SET utf8mb4;
CREATE USER 'phpman139'@'127.0.0.1'
    IDENTIFIED BY 'REPLACE_WITH_LAB_PASSWORD'
    REQUIRE SSL;

-- Следующий GRANT для partial_revokes=0 (OFF): \_ означает буквальный знак _.
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP
    ON `php\_manual\_x139`.* TO 'phpman139'@'127.0.0.1';

SHOW GRANTS FOR 'phpman139'@'127.0.0.1';

REPLACE_WITH_LAB_PASSWORD замените своим паролем отдельной лаборатории. SQL предполагает новые имена: при сообщении о существующем объекте не удаляйте чужую базу или пользователя. SELECT показывает режим partial_revokes: приведённый GRANT рассчитан на0/OFF и экранирует подчёркивания, чтобы они не стали шаблоном имени базы. При1/ON используйте в GRANT обычное имя php_manual_x139 без обратных косых черт; глобальную настройку менять не нужно. SHOW GRANTS позволяет увидеть выданные права.

В архиве каждого примера лежат example.php, lab.php и README.txt. До запуска задайте PHPMAN_MYSQLX_URI с учебной учётной записью и PHPMAN_MYSQLX_SCHEMA с именем заранее созданной базы. Без любой из переменных выполнение прекращается. URI допускает только mysqlx:// с буквальным127.0.0.1 либо[::1] и явным TCP-портом; socket, список hosts и другое имя базы wrapper не выбирает за читателя. Схема должна называться php_manual_x139 либо иметь её учебный суффикс.

$env:PHPMAN_MYSQLX_URI = 'mysqlx://phpman139:URL_ENCODED_LAB_PASSWORD@127.0.0.1:33140?ssl-mode=required'
$env:PHPMAN_MYSQLX_SCHEMA = 'php_manual_x139'
& 'C:\PATH\TO\PHP83\php.exe' -c 'C:\PATH\TO\PHP83\php.ini' .\example.php

Выполните эти команды PowerShell из папки распакованного примера. URL_ENCODED_LAB_PASSWORD — заполнитель для percent-encoded формы того же пароля; C:\PATH\TO\PHP83 — заполнитель полного пути к вашему exe/ini. Например, [Uri]::EscapeDataString('ваш пароль') преобразует пароль для компонента URI; в CREATE USER используется исходный пароль. Порт33140 относится к нашему X-стенду: проверьте фактический X-порт своей установки (обычный стандарт33060), а не подставляйте classic3306/33139. ssl-mode=required требует шифрование; для удалённого сервера проверку сертификата и доверия настраивают отдельно. Реальные закрытые credentials стенда в этих командах не используются.

lab.php проверяет конфигурацию, делает случайные имена mysql139_*, удаляет только имена, созданные данным запуском, и сохраняет отчёт. Все предметные вызовы API видны в example.php. finally выполняет cleanup и закрывает Session даже при исключении. Программа не создаёт и не удаляет схему. Полный URI и пароль не включаются в отчёт или архив.

Откройте result.html после успешного запуска: там таблица наблюдений и раскрываемые документы. result.json содержит реальные данные, проверки и версии, metrics.json — итог очистки. Сопоставьте свой вывод с ожидаемой таблицей. Синтаксическая проверка php -l не проверяет подключение к MySQL и получение документов.

Шесть ступеней от сеанса до страниц каталога

Базовый официальный маршрут начинается с getSession, продолжается Schema/Collection, добавлением и поиском. В нашем варианте схема уже подготовлена отдельно: первые два действия различают соединение, имя коллекции и её создание, третье даёт одну реально сохранённую карточку. Затем растут число товаров, фильтры и размер выдачи.

ШагВидимый результат
1. Установить X-сеансОтвет сервера и доступная учебная схема без записи.
2. Создать коллекциюПереход от отсутствующего имени к пустому каталогу.
3. Открыть сохранённую лампуЧисло, строка и список после getOne; null для отсутствующей карточки.
4. Получить квитанцию нескольких товаровСерверные ID связаны с фактическими SKU и сохранены в JSON.
5. Отобрать карточкиДва товара выбранной мастерской без внутреннего поля.
6. Разделить каталог на страницыA,B и C,D; конец результата и пустая страница.

Документ можно передать в add как PHP-массив либо подготовленную JSON-строку. json_encode преобразует PHP-данные в строку JSON, когда нужна именно строковая форма. Сервер добавляет _id при его отсутствии. Не полагайтесь на алфавитный порядок полей в распечатке: он может отражать внутреннее хранение JSON. Для нескольких документов DocResult допускает foreach; последовательный обход и остановка разобраны на шестом шаге.

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

Получить первый ответ X Protocol и найти учебную схему

Вы хотите хранить каталог документов и сначала проверить, что PHP действительно разговаривает с X Plugin. Подключение MySQLi к classic-порту этого не доказывает. Первая программа ничего не записывает: она получает Session, версию сервера и список доступных учебному пользователю схем.

Путь данных этой программы
  1. PHPMAN_MYSQLX_URI задаёт адрес X-порта и учётную запись
  2. getSession возвращает объект установленного сеанса
  3. getSchemas возвращает доступные объекты Schema
  4. getName даёт имена; сравниваем с обязательной PHPMAN_MYSQLX_SCHEMA
  5. finally закрывает Session

Как читать вызовы

Вызов mysql_xdevapi\getSession($config['uri']) передаёт одну строку URI. Обратная косая черта отделяет пространство имён PHP от имени функции. $session = сохраняет возвращённый объект. $session->getSchemas() вызывает метод без аргументов; foreach рассматривает каждый Schema как $item, а [] добавляет имя в массив. getServerVersion() возвращает целое число вида 80413, а не число с десятичной дробью. Сравнение >=80000 проверяет ветку сервера; точное значение сохраняется отдельно.

Ожидаемый видимый результат

НаблюдениеРезультат
X-сеанс открытда
Сервер MySQL 8 или новееда
Учебная схема виднада
Создано коллекций0

Самостоятельная программа

Получить первый ответ X Protocol и найти учебную схемуСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $schemas = $session->getSchemas();
    $names = [];
    foreach ($schemas as $item) {$names[] = $item->getName();}
    $hasSchema = in_array($config['schema'], $names, true);
    $serverVersion = $session->getServerVersion();
    $rows = [['X-сеанс открыт', $session instanceof mysql_xdevapi\Session],
        ['Сервер MySQL 8 или новее', $serverVersion >= 80000],
        ['Учебная схема видна', $hasSchema], ['Создано коллекций', count($owned)]];
    $checks = ['session_type'=>$session instanceof mysql_xdevapi\Session,
        'server_version'=>$serverVersion >= 80000, 'schema_visible'=>$hasSchema, 'read_only'=>$owned === []];
    $observations = ['visible_schema_names'=>$names, 'server_version'=>$serverVersion];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-first-session', 'Получить первый ответ X Protocol и найти учебную схему', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
X-сеанс открыт — да
Сервер MySQL 8 или новее — да
Учебная схема видна — да
Создано коллекций — 0

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

getSchemas показывает схемы, доступные данной учётной записи, а не обязательно все схемы администратора. Ошибка соединения останавливает программу; отсутствие модуля, неправильный X-порт, выключенный X Plugin, аутентификация и TLS — разные причины. Пароль и полный URI не печатаются. Версии в result.json — наблюдения процесса, таблица выше помогает сравнить свой результат.

PHP-модуль загружен, но сервер отвечает invalid packet type при соединении X DevAPI. Реальная ситуация на Stack Overflow. Проверяем X Plugin, выбранный X-порт и реальный getSession; не переносим старый ответ с отключением SSL и connect-timeout5000 как готовый рецепт.

Composer сообщает об отсутствии ext-mysql_xdevapi, а установка PHP-библиотеки не решает проблему платформы. Реальная ситуация на Stack Overflow. Отделяем системный модуль от Composer-пакета, выбираем DLL под конкретный PHP и проверяем этот процесс через --ini/-m/--ri.

Попробуйте изменить

Удалите PHPMAN_MYSQLX_SCHEMA из окружения. Должна ли программа попытаться выбрать какую-нибудь базу сама?

Как проверить решение

Нет. x139Config выдаст понятный отказ до getSession. После возврата переменной программа снова должна показать видимую заранее созданную схему.

Отличить адрес коллекции от её создания

Нужна пустая папка каталога, но переменная $collection сама по себе ещё не доказывает, что такая коллекция хранится на сервере. Получим handle — объект с адресом — до создания, затем создадим коллекцию и повторим проверку через прежний объект.

Путь данных этой программы
  1. getCollection($name) создаёт PHP-объект доступа
  2. existsInDatabase отвечает false для нового случайного имени
  3. createCollection создаёт коллекцию в учебной схеме
  4. Прежний handle теперь видит её; count возвращает 0
  5. Другой handle с тем же именем обращается к той же коллекции

Как читать вызовы

getCollection принимает имя и возвращает Collection. Это похоже на подписанный адрес папки, а не на саму папку: имя можно знать до её существования. existsInDatabase() обращается к базе и возвращает bool; if проверяет его перед созданием. createCollection($name) уже выполняет действие на сервере и возвращает Collection. count() здесь считает сохранённые документы, а не подготовленные операции. $owned[] регистрирует успешно созданное имя для finally.

Ожидаемый видимый результат

НаблюдениеРезультат
До создания коллекция существоваланет
После создания существуетда
Документов в новой коллекции0
Другой handle ведёт к тому же именида

Самостоятельная программа

Отличить адрес коллекции от её созданияСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $name = x139Name('handles');
    $handle = $schema->getCollection($name);
    $existed = $handle->existsInDatabase();
    if ($existed) {throw new RuntimeException('Случайное имя уже занято.');}
    $collection = $schema->createCollection($name);
    $owned[] = $name;

    $after = $handle->existsInDatabase();
    $empty = $collection->count();
    $again = $schema->getCollection($name);
    $rows = [['До создания коллекция существовала', $existed], ['После создания существует', $after],
        ['Документов в новой коллекции', $empty], ['Другой handle ведёт к тому же имени', $again->getName() === $collection->getName()]];
    $checks = ['initially_absent'=>$existed === false, 'created'=>$after, 'empty'=>$empty === 0,
        'same_name'=>$again->getName() === $collection->getName(), 'same_schema'=>$again->getSchema()->getName() === $schema->getName()];
    $observations = ['collection_name'=>$name, 'schema_name'=>$schema->getName(), 'second_handle_exists'=>$again->existsInDatabase()];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-collection-handles', 'Отличить адрес коллекции от её создания', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
До создания коллекция существовала — нет
После создания существует — да
Документов в новой коллекции — 0
Другой handle ведёт к тому же имени — да

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

Handle не является копией документов и не удерживает неизменный снимок их состояния. Между проверкой и созданием возможна гонка; случайный суффикс и отдельная схема уменьшают пересечение лабораторий, но не превращают две команды в одну. Не удаляйте занятую коллекцию, чтобы «починить» запуск.

Попробуйте изменить

Переставьте getCollection после createCollection. Изменится ли число документов? Что перестанет демонстрировать программа?

Как проверить решение

Коллекция всё равно пуста. Исчезнет наблюдение того, что уже полученный объект доступа переживает переход от отсутствующего имени к существующей коллекции.

Сохранить одну лампу и открыть именно её карточку

Теперь сохраним одну понятную карточку лампы: название, целую цену и список вариантов. Поле _id выбрано явно, чтобы повторное чтение адресовало тот же документ. Между add и execute проверим, что каталог ещё пуст.

Путь данных этой программы
  1. PHP-массив: _id LAMP-1, price1200, options из двух строк
  2. add возвращает CollectionAdd; Collection::count пока0
  3. execute отправляет запись и возвращает Result
  4. getOne(LAMP-1) заново читает документ
  5. getOne(NO-SUCH) даёт null — карточки нет

Как читать вызовы

Квадратные скобки задают массив, => связывает ключ со значением. _id и sku — разные поля: _id однозначно адресует документ; артикул sku имеет смысл для каталога. Число1200 записано без кавычек, вложенные скобки задают список options. add принимает этот массив, а ->execute() вызывает метод у возвращённой операции. getOne получает строковый _id; поля результата читаются через $saved['name']. null означает отсутствие документа, поэтому в рабочем экране такую ветвь проверяют до доступа к полям.

Ожидаемый видимый результат

НаблюдениеРезультат
До execute документов0
Добавлено документов1
Название из базыЛампа O'Neal
Цена из базы1200
Варианты из базынастольная, USB
Неизвестный IDnull

Самостоятельная программа

Сохранить одну лампу и открыть именно её карточкуСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $name = x139Name('one');
    $handle = $schema->getCollection($name);
    $existed = $handle->existsInDatabase();
    if ($existed) {throw new RuntimeException('Случайное имя уже занято.');}
    $collection = $schema->createCollection($name);
    $owned[] = $name;

    $document = ['_id'=>'LAMP-1', 'sku'=>'LAMP', 'name'=>"Лампа O'Neal", 'price'=>1200,
        'options'=>['настольная','USB']];
    $operation = $collection->add($document);
    $before = $collection->count();
    $receipt = $operation->execute();
    $saved = $collection->getOne('LAMP-1');
    $missing = $collection->getOne('NO-SUCH') ?? null;
    $rows = [['До execute документов', $before], ['Добавлено документов', $receipt->getAffectedItemsCount()],
        ['Название из базы', $saved['name']], ['Цена из базы', $saved['price']],
        ['Варианты из базы', implode(', ', $saved['options'])], ['Неизвестный ID', $missing]];
    $checks = ['prepared_only'=>$before === 0, 'one_inserted'=>$receipt->getAffectedItemsCount() === 1,
        'document_array'=>is_array($saved), 'name_roundtrip'=>$saved['name'] === $document['name'],
        'number_roundtrip'=>$saved['price'] === 1200, 'array_roundtrip'=>$saved['options'] === $document['options'],
        'missing_is_null'=>$missing === null, 'stored_count'=>$collection->count() === 1];
    $observations = ['submitted_document'=>$document, 'read_document'=>$saved, 'missing_document'=>$missing];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-one-document', 'Сохранить одну лампу и открыть именно её карточку', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
До execute документов — 0
Добавлено документов — 1
Название из базы — Лампа O'Neal
Цена из базы — 1200
Варианты из базы — настольная, USB
Неизвестный ID — null

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

Сначала ответ записи, затем отдельное чтение: входной массив не выдаётся за результат сохранения. JSON-объект данных не равен объекту PHP-класса Collection. Имена полей в возвращаемом массиве могут иметь иной порядок из-за внутреннего JSON-хранения; сравнивайте значения по ключам. Явный _id должен быть уникальным: повтор add не становится обновлением. PHP Manual обещает null для отсутствующего документа, но в проверенном PECL mysql_xdevapi8.0.30 getOne возвращает внутреннее неопределённое значение UNDEF: обычное присваивание может оставить переменную неопределённой. Поэтому в этой версии запись getOne('NO-SUCH') ?? null явно нормализует отсутствие в null. Оператор ?? выбирает правую часть при отсутствии значения; после него проверка $missing === null имеет определённый смысл. Это совместимость с конкретной версией, а не правило хранения документов. Альтернативный find с bind и execute()->fetchOne() в том же окружении вернул обычный null.

Попробуйте изменить

Измените цену в исходной лампе на1300 и запустите в новой собственной коллекции. Какая часть ожидаемого результата и проверки должна измениться?

Как проверить решение

В чтении должна появиться1300, а проверка number_roundtrip должна ожидать1300. Число документов остаётся1, и _id по-прежнему LAMP-1.

Связать серверные ID с двумя действительно сохранёнными товарами

Если карточкам ещё не назначены ключи, сервер может создать _id сам. Оператору нужна квитанция, по которой можно снова открыть каждую добавленную карточку. Добавим массив и JSON-строку одной операцией, получим ID и прочитаем именно эти документы.

Путь данных этой программы
  1. add получает два документа без _id
  2. execute возвращает Result с двумя generated IDs
  3. Для каждого настоящего ID вызываем getOne
  4. Проверяем совпадение _id и список SKU: CABLE, LED
  5. Отдельный add с MANUAL-1 показывает пустой generatedIds при успешной записи

Как читать вызовы

В add($array, $json) запятая разделяет два документа. JSON-строка уже содержит кавычки вокруг имён полей; json_encode нужен, когда такую строку строят из PHP-данных, а не при передаче готового массива. getGeneratedIds() возвращает список только созданных сервером ID этой операции. foreach передаёт каждый ID в getOne. Проверка связывает ID из квитанции с _id из прочитанного документа; сортируются только SKU для стабильного вывода, сами идентификаторы сохраняются без замены.

Ожидаемый видимый результат

НаблюдениеРезультат
Добавлено первой операцией2
Получено серверных ID2
ID связаны с прочитанными документамида
Артикулы по этим IDCABLE, LED
Generated IDs при явном _id0
Всего документов после третьего товара3

Самостоятельная программа

Связать серверные ID с двумя действительно сохранёнными товарамиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $name = x139Name('receipt');
    $handle = $schema->getCollection($name);
    $existed = $handle->existsInDatabase();
    if ($existed) {throw new RuntimeException('Случайное имя уже занято.');}
    $collection = $schema->createCollection($name);
    $owned[] = $name;

    $receipt = $collection->add(['sku'=>'LED','name'=>'Лампа'], '{"sku":"CABLE","name":"Кабель"}')->execute();
    $ids = $receipt->getGeneratedIds();
    $readBack = [];
    $linked = count($ids) === 2 && count(array_unique($ids)) === 2;
    foreach ($ids as $id) {
        $doc = $collection->getOne($id);
        $linked = $linked && is_string($id) && $id !== '' && is_array($doc) && $doc['_id'] === $id;
        $readBack[] = ['generated_id'=>$id, 'document'=>$doc];
    }
    $skus = array_column(array_column($readBack, 'document'), 'sku');
    sort($skus);
    $explicit = $collection->add(['_id'=>'MANUAL-1','sku'=>'STAND','name'=>'Подставка'])->execute();
    $explicitIds = $explicit->getGeneratedIds();
    $explicitRead = $collection->getOne('MANUAL-1');
    $rows = [['Добавлено первой операцией', $receipt->getAffectedItemsCount()], ['Получено серверных ID', count($ids)],
        ['ID связаны с прочитанными документами', $linked], ['Артикулы по этим ID', implode(', ', $skus)],
        ['Generated IDs при явном _id', count($explicitIds)], ['Всего документов после третьего товара', $collection->count()]];
    $checks = ['two_inserted'=>$receipt->getAffectedItemsCount() === 2, 'two_distinct_ids'=>count($ids) === 2 && count(array_unique($ids)) === 2,
        'all_ids_read_back'=>$linked, 'expected_skus'=>$skus === ['CABLE','LED'],
        'explicit_not_generated'=>$explicitIds === [], 'explicit_read'=>$explicitRead['sku'] === 'STAND', 'stored_three'=>$collection->count() === 3];
    $observations = ['generated_ids'=>$ids, 'generated_id_readback'=>$readBack,
        'explicit_document'=>$explicitRead, 'explicit_generated_ids'=>$explicitIds,
        'warnings'=>$receipt->getWarnings(), 'warnings_count'=>$receipt->getWarningsCount()];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-generated-receipt', 'Связать серверные ID с двумя действительно сохранёнными товарами', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Добавлено первой операцией — 2
Получено серверных ID — 2
ID связаны с прочитанными документами — да
Артикулы по этим ID — CABLE, LED
Generated IDs при явном _id — 0
Всего документов после третьего товара — 3

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

Не вычисляйте следующий ID из предыдущего и не подставляйте пример идентификатора из статьи. Наличие SKU не делает его автоматически уникальным ключом: здесь явное _id использует отдельное значение MANUAL-1. getAffectedItemsCount относится к конкретной операции, Collection::count — ко всей коллекции. getAutoIncrementValue предназначен для иной модели автоинкремента и не заменяет getGeneratedIds.

Попробуйте изменить

Добавьте третий документ без _id в первую операцию. Какие связи должны появиться в JSON квитанции?

Как проверить решение

Три реальных generated IDs, три записи readback и три ожидаемых SKU. После отдельного товара MANUAL-1 общий count станет4; проверка его generatedIds останется пустой.

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

Посетитель выбирает мастерскую с апострофом в названии и бюджет1000. Выдача должна показать только подходящие товары и поля карточки. Текст ввода не должен становиться частью условия поиска, а служебное internal не нужно отправлять на экран.

Путь данных этой программы
  1. Автор задаёт структуру category=:category AND price<=:ceiling
  2. bind связывает категорию и число1000 с именованными местами
  3. fields оставляет sku/name/price; sort задаёт порядок
  4. execute получает DocResult; fetchAll создаёт массив карточек
  5. Строка, похожая на выражение, ищется буквально и даёт0 совпадений

Как читать вызовы

find возвращает настраиваемую операцию CollectionFind. Двоеточие входит в выражение :category, но ключ массива bind записывается category без двоеточия. fields принимает строку или массив имён; это проекция — выбор выходных полей, а не изменение сохранённых документов. sort принимает порядок ASC либо DESC; второе поле разрешает равенство первого. execute возвращает DocResult, fetchAll — массив документов. Все четыре шага показаны отдельно до компактных цепочек.

Ожидаемый видимый результат

НаблюдениеРезультат
Найдено доступных товаров2
Артикулы по возрастанию ценыCABLE, LED
Поля ограничены карточкойда
Чужое выражение осталось значениемда

Самостоятельная программа

Построить каталог по связанным значениям и выбрать поля карточкиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $name = x139Name('filter');
    $handle = $schema->getCollection($name);
    $existed = $handle->existsInDatabase();
    if ($existed) {throw new RuntimeException('Случайное имя уже занято.');}
    $collection = $schema->createCollection($name);
    $owned[] = $name;

    $category = "Мастерская O'Neal";
    $collection->add(
        ['_id'=>'A','sku'=>'LED','name'=>'Лампа','category'=>$category,'price'=>900,'internal'=>'не показывать'],
        ['_id'=>'B','sku'=>'CABLE','name'=>'Кабель','category'=>$category,'price'=>400,'internal'=>'не показывать'],
        ['_id'=>'C','sku'=>'PRO','name'=>'Большая лампа','category'=>$category,'price'=>2000,'internal'=>'не показывать'],
        ['_id'=>'D','sku'=>'GARDEN','name'=>'Фонарь','category'=>'Сад','price'=>300,'internal'=>'не показывать']
    )->execute();
    $request = $collection->find('category = :category and price <= :ceiling');
    $request->bind(['category'=>$category, 'ceiling'=>1000]);
    $request->fields(['sku','name','price']);
    $request->sort('price ASC', 'sku ASC');
    $result = $request->execute();
    $documents = $result->fetchAll();
    $none = $collection->find('category = :category')->bind(['category'=>"' OR true OR '"])->execute()->fetchAll();
    $projection = true;
    foreach ($documents as $doc) {
        $keys = array_keys($doc); sort($keys);
        $projection = $projection && $keys === ['name','price','sku'];
    }
    $rows = [['Найдено доступных товаров', count($documents)],
        ['Артикулы по возрастанию цены', implode(', ', array_column($documents,'sku'))],
        ['Поля ограничены карточкой', $projection], ['Чужое выражение осталось значением', count($none) === 0]];
    $checks = ['two_matches'=>count($documents) === 2, 'expected_order'=>array_column($documents,'sku') === ['CABLE','LED'],
        'projection_only'=>$projection, 'bound_string_not_expression'=>$none === [],
        'result_type'=>$result instanceof mysql_xdevapi\DocResult, 'prices_numeric'=>array_column($documents,'price') === [400,900]];
    $observations = ['bound_values'=>['category'=>$category,'ceiling'=>1000], 'catalog'=>$documents, 'unmatched_input_result'=>$none];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-bound-catalog', 'Построить каталог по связанным значениям и выбрать поля карточки', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Найдено доступных товаров — 2
Артикулы по возрастанию цены — CABLE, LED
Поля ограничены карточкой — да
Чужое выражение осталось значением — да

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

bind связывает значения, а не имена полей, операторы или направление сортировки. Эти части выбирайте из своего допустимого списка. Поля fixture имеют согласованные типы: price — целое, category — строка; фильтр не исправляет данные неверного типа. JSON null и отсутствующее свойство требуют отдельного решения и не тождественны SQL NULL. Проекция уменьшает передаваемые данные, но сама по себе не заменяет проверку прав доступа.

Разница null и отсутствующего свойства подробно объяснена в трёх состояниях JSON/SQL. Параметры и допустимая структура выражения сравниваются с разрешёнными вариантами сортировки.

Ожидаемый поиск null не совпадает с поведением JSON null и отсутствующего поля. Реальная ситуация на Stack Overflow. Не приравниваем JSON null, отсутствующее свойство и SQL NULL. В текущем каталоге фиксируем числовую цену и строковую категорию; полный разбор различий уже находится в SQL JSON. Повторяемого решения всех вариантов null через X expression этот пакет не заявляет.

Попробуйте изменить

Уменьшите ceiling до500. Сколько карточек останется и исчезнет ли поле internal из сохранённых документов?

Как проверить решение

Останется CABLE за400. internal не удаляется из базы: fields ограничивает ответ конкретного запроса. Для изменения полей нужен отдельный modify.

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

Каталог вырос до пяти товаров. Покажем по два товара на странице, затем научимся отличать пустую выдачу от ошибки и конец чтения от нового документа. Две лампы имеют одинаковую цену: вторичная сортировка sku делает порядок fixture определённым.

Путь данных этой программы
  1. sort: price ASC, затем sku ASC
  2. limit(2) задаёт максимум; offset(0/2) пропускает0/2 документа
  3. fetchOne последовательно возвращает A, B, затем null
  4. Новый запрос второй страницы даёт C,D через fetchAll
  5. offset99 даёт []; свежий DocResult можно обходить foreach

Как читать вызовы

В while присваивание $doc = ... сохраняет очередной документ; !== null проверяет конец, а фигурные скобки повторяют добавление в $first. Не пишите бесконечный цикл без проверки результата чтения. limit задаёт максимум, offset — сколько совпадений пропустить, а не номер страницы. Для страницы с номером2 и размером2 смещение равно(2-1)*2. DocResult допускает foreach; для альтернативного способа обхода создаём свежий результат, а не предполагаем перемотку уже прочитанного.

Ожидаемый видимый результат

НаблюдениеРезультат
Первая страницаA, B
Вторая страницаC, D
После конца fetchOnenull
За пределами каталога0
foreach по свежему DocResultA, B
Всего в коллекции5

Самостоятельная программа

Прочитать две страницы каталога и распознать конец результатаСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x139Config();
$session = mysql_xdevapi\getSession($config['uri']);
$schema = null;
$owned = [];
$removed = [];
$rows = $checks = $observations = [];
try {
    $schema = $session->getSchema($config['schema']);
    if (!$schema->existsInDatabase()) {
        throw new RuntimeException('Учебная схема не существует: подготовьте её отдельно.');
    }
    $runtime = ['php'=>PHP_VERSION, 'extension'=>phpversion('mysql_xdevapi'),
        'server_version'=>$session->getServerVersion(), 'schema'=>$config['schema'],
        'host'=>$config['host'], 'port'=>$config['port']];
    $name = x139Name('pages');
    $handle = $schema->getCollection($name);
    $existed = $handle->existsInDatabase();
    if ($existed) {throw new RuntimeException('Случайное имя уже занято.');}
    $collection = $schema->createCollection($name);
    $owned[] = $name;

    $collection->add(
        ['_id'=>'A','sku'=>'A','price'=>100], ['_id'=>'B','sku'=>'B','price'=>100],
        ['_id'=>'C','sku'=>'C','price'=>200], ['_id'=>'D','sku'=>'D','price'=>300], ['_id'=>'E','sku'=>'E','price'=>400]
    )->execute();
    $firstResult = $collection->find()->sort('price ASC','sku ASC')->limit(2)->offset(0)->execute();
    $first = [];
    while (($doc = $firstResult->fetchOne()) !== null) {$first[] = $doc;}
    $end = $firstResult->fetchOne();
    $second = $collection->find()->sort('price ASC','sku ASC')->limit(2)->offset(2)->execute()->fetchAll();
    $beyond = $collection->find()->sort('price ASC','sku ASC')->limit(2)->offset(99)->execute()->fetchAll();
    $iterated = [];
    foreach ($collection->find()->sort('sku ASC')->limit(2)->execute() as $doc) {$iterated[] = $doc['sku'];}
    $firstSkus = array_column($first,'sku');
    $secondSkus = array_column($second,'sku');
    $rows = [['Первая страница', implode(', ', $firstSkus)], ['Вторая страница', implode(', ', $secondSkus)],
        ['После конца fetchOne', $end], ['За пределами каталога', count($beyond)],
        ['foreach по свежему DocResult', implode(', ', $iterated)], ['Всего в коллекции', $collection->count()]];
    $checks = ['first_page'=>$firstSkus === ['A','B'], 'second_page'=>$secondSkus === ['C','D'],
        'null_at_end'=>$end === null, 'empty_beyond'=>$beyond === [], 'iterable'=>$iterated === ['A','B'],
        'no_overlap'=>array_intersect($firstSkus,$secondSkus) === [], 'full_count'=>$collection->count() === 5];
    $observations = ['first_page'=>$first, 'second_page'=>$second, 'end_fetch'=>$end, 'beyond'=>$beyond,
        'iterated_skus'=>$iterated, 'unchanged_fixture'=>true];
} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x139Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}
x139Report('mysql139-x-page-results', 'Прочитать две страницы каталога и распознать конец результата', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Первая страница — A, B
Вторая страница — C, D
После конца fetchOne — null
За пределами каталога — 0
foreach по свежему DocResult — A, B
Всего в коллекции — 5

Файл получает настоящий ответ X Protocol, отдельно читает данные и в finally очищает только свою коллекцию. Сравните stdout и созданную таблицу с ожидаемым результатом.

После своего запуска откройте result.html из папки примера. JSON рядом сохраняет реальные значения, а не подставленные строки ожидаемого результата.

Таблица сохранённого запуска · JSON сохранённого запуска.

Ошибки и границы

fetchAll материализует всю выбранную выдачу в PHP-массиве; ограничивайте размер страницы. fetchOne позволяет обрабатывать документы постепенно, но этот пример не измеряет внутреннюю буферизацию драйвера. Две страницы демонстрируют неизменяемую fixture: вставки/удаления между запросами могут сдвинуть offset. При большом смещении серверу всё равно нужно пропускать данные; для растущего каталога изучите курсорную пагинацию, индексы и согласованность отдельно.

Следующий вариант навигации для меняющегося каталога — продолжение после пары цена + ID. Это отдельный SQL-урок; он объясняет идею границы страницы, а не подменяет методы X DevAPI.

Попробуйте изменить

Поставьте limit(3) и offset(3) для второй страницы. Какие SKU вернутся? Что будет при offset(5)?

Как проверить решение

Для второй страницы вернутся D,E; при offset5 выдача пуста. Collection::count останется5: лимит и смещение не меняют коллекцию.

Найти класс или метод по нужному результату

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

APIЗадача
SessionОдин установленный сеанс связывает операции с сервером и границами транзакции. Его получают через getSession, а не new Session. Две Session — два отдельных сеанса.
SchemaSchema представляет базу MySQL и даёт доступ к коллекциям и реляционным таблицам. Сам getSchema не создаёт базу. Публичное name описывает имя объекта; изменение PHP-свойства не является командой переименования базы.
CollectionCollection — объект доступа к набору JSON-документов. Он хранит связь с именем и схемой, а не весь каталог в памяти PHP. Получается через Schema. Поле name описывает имя; данные меняют методами CRUD.
CollectionAddCollectionAdd описывает ещё не отправленное добавление. Collection::add возвращает этот объект; execute отправляет действие и возвращает квитанцию Result. Повторный execute не следует использовать как безопасный повтор бизнес-операции.
CollectionFindCollectionFind хранит условие и настройки запроса. Каждый метод настройки возвращает CollectionFind для дальнейшей цепочки; execute возвращает уже DocResult. Найденные документы не хранятся в самой строке условия.
DocResultDocResult содержит результат поиска документов и сведения о предупреждениях. Создаётся исполнением CollectionFind; документы получают методами чтения или foreach. Это иной объект, чем Result квитанции записи.
ResultResult — квитанция завершённой операции записи: затронутое количество, серверные идентификаторы и предупреждения. Она не заменяет чтение сохранённых полей и не означает число товаров во всей коллекции.
getSessionОткрыть X-сеанс по URI и получить объект для дальнейшей работы.
Session::getServerVersionОтличить версию сервера от версии PHP-модуля.
Schema::createCollectionСоздать место для документов и при необходимости задать проверку формы.
Schema::getCollectionПолучить адресный объект доступа без создания коллекции.
Collection::existsInDatabaseОтличить существующую коллекцию от одного лишь PHP-объекта.
Collection::addПодготовить вставку массива или JSON-документа, сохранив границу отправки.
Collection::countУзнать количество документов в коллекции целиком.
Collection::getOneОткрыть конкретный документ по _id либо получить отсутствие.
Collection::findЗадать условие выбора и получить настраиваемый запрос.
CollectionAdd::executeОтправить подготовленное добавление на сервер.
CollectionFind::bindПередать пользовательские значения отдельно от выражения поиска.
CollectionFind::fieldsОставить в ответе поля, нужные экрану.
CollectionFind::sortДать выдаче определённый порядок.
CollectionFind::limitОграничить размер выдачи для страницы каталога.
CollectionFind::offsetПропустить уже показанную часть стабильной выдачи.
CollectionFind::executeИсполнить настроенный поиск и получить объект чтения.
DocResult::fetchOneПолучить очередной документ и явно распознать конец.
DocResult::fetchAllПолучить выбранные документы в виде списка для экрана.
Result::getGeneratedIdsПолучить настоящие серверные ключи только этой операции.
Result::getAffectedItemsCountПрочитать количество затронутых элементов операции.

От чтения каталога к управляемому изменению

Теперь можно пройти весь путь: установить X-сеанс, создать свою коллекцию, отправить документ, прочитать его, связать с квитанцией серверный ID и выдать небольшую страницу выбранных полей. Сохраните это разделение в своём экране: параметры запроса, факт исполнения и данные для показа имеют разные источники.

Продолжение — изменение свойств, замена и проверяемая квитанция. Для общей модели базы вернитесь к связи PHP, сервера и данных, для иных задач хранения — к свойствам JSON в SQL.

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

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

mysql_xdevapi\SessionОдин установленный сеанс связывает операции с сервером и границами транзакции. Его получают через getSession, а не new Session. Две Session — два отдельных сеанса.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\Session

Один установленный сеанс связывает операции с сервером и границами транзакции. Его получают через getSession, а не new Session. Две Session — два отдельных сеанса.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\Session {
    public function close(): bool;
    public function commit(): Object;
    private function __construct();
    public function createSchema(string $schema_name): Schema;
    public function dropSchema(string $schema_name): bool;
    public function generateUUID(): string;
    public function getDefaultSchema(): ?Schema;
    public function getSchema(string $schema_name): Schema;
    public function getSchemas(): array;
    public function getServerVersion(): int;
    public function listClients(): array;
    public function quoteName(string $name): string;
    public function releaseSavepoint(string $name): void;
    public function rollback(): void;
    public function rollbackTo(string $name): void;
    public function setSavepoint(string $name = ?): string;
    public function sql(string $query): SqlStatement;
    public function startTransaction(): void;
}
Член APIНазначение
Session::close — PHP ManualЗавершить сеанс.
Session::commit — PHP ManualЗафиксировать текущую транзакцию.
Session::__construct — PHP ManualЗакрытый конструктор; вход через getSession.
Session::createSchema — PHP ManualСоздать схему по имени.
Session::dropSchema — PHP ManualУдалить схему; не действие нашей лаборатории.
Session::generateUUID — PHP ManualПолучить UUID.
Session::getDefaultSchema — PHP ManualПолучить схему по умолчанию, если она задана.
Session::getSchema — PHP ManualПолучить объект доступа по имени.
Session::getSchemas — PHP ManualПолучить доступные схемы.
Session::getServerVersionПрочитать версию сервера данного сеанса.
Session::listClients — PHP ManualПолучить сведения о клиентах.
Session::quoteName — PHP ManualЗаключить идентификатор в нужные кавычки.
Session::releaseSavepoint — PHP ManualУдалить точку сохранения.
Session::rollback — PHP ManualОткатить транзакцию.
Session::rollbackTo — PHP ManualОткатиться к именованной точке.
Session::setSavepoint — PHP ManualСоздать точку сохранения и получить имя.
Session::sql — PHP ManualПодготовить SQL-операцию через тот же сеанс.
Session::startTransaction — PHP ManualНачать транзакцию.

Два применения

Диагностика получает версию именно установленного сеанса; URI берётся из проверенного окружения.

$session = mysql_xdevapi\getSession($uri);
$version = $session->getServerVersion();

Исходные данные, полный файл и ожидаемый результат.

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

$schema = $session->getSchema($schemaName);
$collection = $schema->createCollection($ownName);

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\SchemaSchema представляет базу MySQL и даёт доступ к коллекциям и реляционным таблицам. Сам getSchema не создаёт базу. Публичное name описывает имя объекта; изменение PHP-свойства не является командой переименования базы.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\Schema implements DatabaseObject

Schema представляет базу MySQL и даёт доступ к коллекциям и реляционным таблицам. Сам getSchema не создаёт базу. Публичное name описывает имя объекта; изменение PHP-свойства не является командой переименования базы.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\Schema implements DatabaseObject {
    public $name;
    private function __construct();
    public function createCollection(string $name, string $validate = ?): Collection;
    public function dropCollection(string $collection_name): bool;
    public function existsInDatabase(): bool;
    public function getCollection(string $name): Collection;
    public function getCollectionAsTable(string $name): Table;
    public function getCollections(): array;
    public function getName(): string;
    public function getSession(): Session;
    public function getTable(string $name): Table;
    public function getTables(): array;
}
Член APIНазначение
Schema::__construct — PHP ManualЗакрытый конструктор.
Schema::createCollectionСоздать коллекцию; необязательное JSON-описание проверки с8.0.20.
Schema::dropCollection — PHP ManualУдалить коллекцию.
Schema::existsInDatabase — PHP ManualПроверить существование схемы.
Schema::getCollectionПолучить объект доступа к коллекции.
Schema::getCollectionAsTable — PHP ManualРассматривать коллекцию через табличный API.
Schema::getCollections — PHP ManualПолучить коллекции схемы.
Schema::getName — PHP ManualПрочитать имя.
Schema::getSession — PHP ManualВернуться к связанному сеансу.
Schema::getTable — PHP ManualПолучить таблицу.
Schema::getTables — PHP ManualПолучить таблицы схемы.

implements перечисляет реализованные контракты: DatabaseObject. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

Два применения

Перед работой подтвердите существование заранее подготовленной учебной базы.

$schema = $session->getSchema($schemaName);
$present = $schema->existsInDatabase();

Исходные данные, полный файл и ожидаемый результат.

Создание и получение второго объекта доступа решают разные задачи.

$collection = $schema->createCollection($ownName);
$another = $schema->getCollection($ownName);

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\CollectionCollection — объект доступа к набору JSON-документов. Он хранит связь с именем и схемой, а не весь каталог в памяти PHP. Получается через Schema. Поле name описывает имя; данные меняют методами CRUD.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\Collection implements SchemaObject

Collection — объект доступа к набору JSON-документов. Он хранит связь с именем и схемой, а не весь каталог в памяти PHP. Получается через Schema. Поле name описывает имя; данные меняют методами CRUD.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\Collection implements SchemaObject {
    public $name;
    public function add(mixed $document): CollectionAdd;
    public function addOrReplaceOne(string $id, string $doc): Result;
    private function __construct();
    public function count(): int;
    public function createIndex(string $index_name, string $index_desc_json): void;
    public function dropIndex(string $index_name): bool;
    public function existsInDatabase(): bool;
    public function find(string $search_condition = ?): CollectionFind;
    public function getName(): string;
    public function getOne(string $id): Document;
    public function getSchema(): Schema;
    public function getSession(): Session;
    public function modify(string $search_condition): CollectionModify;
    public function remove(string $search_condition): CollectionRemove;
    public function removeOne(string $id): Result;
    public function replaceOne(string $id, string $doc): Result;
}
Член APIНазначение
Collection::addПодготовить добавление одного или нескольких документов.
Collection::addOrReplaceOne — PHP ManualДобавить либо целиком заменить документ.
Collection::__construct — PHP ManualЗакрытый конструктор.
Collection::countПосчитать сохранённые документы.
Collection::createIndex — PHP ManualСоздать индекс по JSON-описанию.
Collection::dropIndex — PHP ManualУдалить индекс.
Collection::existsInDatabaseПроверить существование именно коллекции.
Collection::findПодготовить поиск.
Collection::getName — PHP ManualПолучить имя коллекции.
Collection::getOneПрочитать документ по _id; при отсутствии null.
Collection::getSchema — PHP ManualПолучить связанную схему.
Collection::getSession — PHP ManualПолучить связанный сеанс.
Collection::modify — PHP ManualПодготовить изменение по условию.
Collection::remove — PHP ManualПодготовить удаление по условию.
Collection::removeOne — PHP ManualУдалить один документ по _id.
Collection::replaceOne — PHP ManualЦеликом заменить существующий документ.

implements перечисляет реализованные контракты: SchemaObject. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

Document в сокращённой схеме getOne — обозначение данных документа, не встроенный PHP-класс для new. В этом API прочитанные поля используются как массив, а отсутствие обозначается null; различие разобрано в Collection::getOne.

Два применения

Записать одну карточку и затем отдельно проверить сохранённую цену.

$receipt = $collection->add(['_id'=>'LAMP-1','price'=>1200])->execute();
$lamp = $collection->getOne('LAMP-1');

Исходные данные, полный файл и ожидаемый результат.

Выдать подходящие карточки при изменившемся бюджете.

$items = $collection->find('price <= :ceiling')
    ->bind(['ceiling'=>1000])->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\CollectionAddCollectionAdd описывает ещё не отправленное добавление. Collection::add возвращает этот объект; execute отправляет действие и возвращает квитанцию Result. Повторный execute не следует использовать как безопасный повтор бизнес-операции.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\CollectionAdd implements Executable

CollectionAdd описывает ещё не отправленное добавление. Collection::add возвращает этот объект; execute отправляет действие и возвращает квитанцию Result. Повторный execute не следует использовать как безопасный повтор бизнес-операции.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\CollectionAdd implements Executable {
    private function __construct();
    public function execute(): Result;
}
Член APIНазначение
CollectionAdd::__construct — PHP ManualЗакрытый конструктор; создаётся через Collection::add.
CollectionAdd::executeОтправить операцию серверу.

implements перечисляет реализованные контракты: Executable. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

Два применения

Можно отдельно увидеть пустую коллекцию до исполнения подготовленной операции.

$operation = $collection->add(['_id'=>'LAMP-1','price'=>1200]);
$before = $collection->count();
$receipt = $operation->execute();

Исходные данные, полный файл и ожидаемый результат.

Одна операция принимает несколько документов и даёт общую квитанцию.

$receipt = $collection->add(['sku'=>'LED'], '{"sku":"CABLE"}')->execute();
$ids = $receipt->getGeneratedIds();

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\CollectionFindCollectionFind хранит условие и настройки запроса. Каждый метод настройки возвращает CollectionFind для дальнейшей цепочки; execute возвращает уже DocResult. Найденные документы не хранятся в самой строке условия.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\CollectionFind implements Executable, CrudOperationBindable, CrudOperationLimitable, CrudOperationSortable

CollectionFind хранит условие и настройки запроса. Каждый метод настройки возвращает CollectionFind для дальнейшей цепочки; execute возвращает уже DocResult. Найденные документы не хранятся в самой строке условия.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\CollectionFind implements Executable, CrudOperationBindable, CrudOperationLimitable, CrudOperationSortable {
    public function bind(array $placeholder_values): CollectionFind;
    private function __construct();
    public function execute(): DocResult;
    public function fields(string $projection): CollectionFind;
    public function groupBy(string $sort_expr): CollectionFind;
    public function having(string $sort_expr): CollectionFind;
    public function limit(int $rows): CollectionFind;
    public function lockExclusive(int $lock_waiting_option = ?): CollectionFind;
    public function lockShared(int $lock_waiting_option = ?): CollectionFind;
    public function offset(int $position): CollectionFind;
    public function sort(string $sort_expr): CollectionFind;
}
Член APIНазначение
CollectionFind::bindСвязать значения с placeholders.
CollectionFind::__construct — PHP ManualЗакрытый конструктор; отдельная страница не документирует его поведение.
CollectionFind::executeИсполнить поиск.
CollectionFind::fieldsВыбрать выходные поля; описание также допускает массив строк.
CollectionFind::groupBy — PHP ManualЗадать группировку.
CollectionFind::having — PHP ManualЗадать условие для агрегатных групп.
CollectionFind::limitОграничить число документов.
CollectionFind::lockExclusive — PHP ManualЗапросить исключительную блокировку.
CollectionFind::lockShared — PHP ManualЗапросить разделяемую блокировку.
CollectionFind::offsetПропустить указанное число совпадений.
CollectionFind::sortУпорядочить; пример Manual допускает несколько аргументов.

implements перечисляет реализованные контракты: Executable, CrudOperationBindable, CrudOperationLimitable, CrudOperationSortable. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

Схема воспроизводит краткие формы Manual. Полный текст CollectionFind::fields допускает массив полей, а пример CollectionFind::sort — несколько строк сортировки. Знак ? у необязательного аргумента в справочной схеме означает, что значение по умолчанию здесь не конкретизировано; не вставляйте такой знак в вызов.

Два применения

Сначала выбрать товары, затем ограничить данные карточки.

$request = $collection->find('category = :category');
$request->bind(['category'=>$category])->fields(['sku','name']);
$result = $request->execute();

Исходные данные, полный файл и ожидаемый результат.

Настройки одной выдачи задают вторую страницу неизменяемого каталога.

$result = $collection->find()->sort('price ASC','sku ASC')
    ->limit(2)->offset(2)->execute();

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\DocResultDocResult содержит результат поиска документов и сведения о предупреждениях. Создаётся исполнением CollectionFind; документы получают методами чтения или foreach. Это иной объект, чем Result квитанции записи.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\DocResult implements BaseResult, Traversable

DocResult содержит результат поиска документов и сведения о предупреждениях. Создаётся исполнением CollectionFind; документы получают методами чтения или foreach. Это иной объект, чем Result квитанции записи.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\DocResult implements BaseResult, Traversable {
    private function __construct();
    public function fetchAll(): array;
    public function fetchOne(): array;
    public function getWarnings(): array;
    public function getWarningsCount(): int;
}
Член APIНазначение
DocResult::__construct — PHP ManualЗакрытый конструктор; результат выдаёт CollectionFind.
DocResult::fetchAllПолучить документы как список ассоциативных массивов; пустой список при отсутствии.
DocResult::fetchOneПолучить очередной документ; описание возврата дополнительно указывает null.
DocResult::getWarnings — PHP ManualПолучить предупреждения последней операции.
DocResult::getWarningsCount — PHP ManualПолучить число предупреждений.

implements перечисляет реализованные контракты: BaseResult, Traversable. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

У fetchOne краткая сигнатура array неполна: описание возврата включает null в конце результата. Для цикла используйте именно эту границу. Traversable позволяет foreach, но не является обещанием перематывать уже прочитанный результат.

Два применения

Небольшая ограниченная выборка превращается в готовый список карточек.

$documents = $request->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

Последовательное чтение прекращается на null; альтернативный foreach показан на свежем результате.

while (($document = $result->fetchOne()) !== null) {
    echo $document['sku'], PHP_EOL;
}

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\ResultResult — квитанция завершённой операции записи: затронутое количество, серверные идентификаторы и предупреждения. Она не заменяет чтение сохранённых полей и не означает число товаров во всей коллекции.

mysql_xdevapi8.0.11+; учебный runtime8.0.30 · mysql_xdevapi

class mysql_xdevapi\Result implements BaseResult, Traversable

Result — квитанция завершённой операции записи: затронутое количество, серверные идентификаторы и предупреждения. Она не заменяет чтение сохранённых полей и не означает число товаров во всей коллекции.

Класс расширения mysql_xdevapi доступен с8.0.11. Его конструктор закрытый (private), поэтому объект возвращает соответствующий API. Ниже справочная схема, а не класс, который нужно объявить в своём файле.

class mysql_xdevapi\Result implements BaseResult, Traversable {
    private function __construct();
    public function getAffectedItemsCount(): int;
    public function getAutoIncrementValue(): int;
    public function getGeneratedIds(): array;
    public function getWarnings(): array;
    public function getWarningsCount(): int;
}
Член APIНазначение
Result::__construct — PHP ManualЗакрытый конструктор; создаётся исполнением операции.
Result::getAffectedItemsCountПолучить число затронутых элементов.
Result::getAutoIncrementValue — PHP ManualПолучить автоинкрементное значение табличной операции.
Result::getGeneratedIdsПолучить созданные сервером _id документов.
Result::getWarnings — PHP ManualПолучить предупреждения.
Result::getWarningsCount — PHP ManualПолучить их количество.

implements перечисляет реализованные контракты: BaseResult, Traversable. Это описание возможностей объектов, а не новые данные каталога. Как интерфейс задаёт договор поведения.

Наличие Traversable в схеме не превращает квитанцию в коллекцию сохранённых карточек. Для нашего добавления полезны счётчик и generated IDs; поля товаров возвращает отдельный запрос. getWarnings/getWarningsCount описывают предупреждения операции, а не исключение, прервавшее её.

Два применения

Одна явная карточка даёт счётчик1; её цену всё равно читают отдельно.

$receipt = $collection->add(['_id'=>'LAMP-1','price'=>1200])->execute();
$added = $receipt->getAffectedItemsCount();

Исходные данные, полный файл и ожидаемый результат.

Квитанция нескольких добавлений даёт адреса для проверенного повторного чтения.

$ids = $receipt->getGeneratedIds();
foreach ($ids as $id) {$saved[] = $collection->getOne($id);}

Исходные данные, полный файл и ожидаемый результат.

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

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

mysql_xdevapi\getSessionОткрыть X-сеанс по URI и получить объект для дальнейшей работы.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

function mysql_xdevapi\getSession(string $uri): mysql_xdevapi\Session

Открыть X-сеанс по URI и получить объект для дальнейшей работы.

ВходСмысл
uriСтрока scheme://[user[:password]@]target[:port][?параметры]. Обязательны mysqlx и target; user/password/port/options необязательны. Обычный X-порт33060. Target API может быть hostname, IPv4/IPv6, Unix socket или Windows named pipe; наш лабораторный wrapper намеренно допускает лишь TCP loopback.

Результат и отказ

Session при успехе; ошибка соединения выбрасывает Exception, а не возвращает пустую коллекцию.

УточнениеКак понимать
authplain, mysql41, external, sha256_mem; применимость связана с настройками аутентификации и шифрования.
connect-timeoutТолько установление соединения, отдельно для каждого host: PHP Manual указывает секунды, положительное целое;0 отключает предел, по умолчанию10. URI имеет приоритет над MYSQLX_CONNECTION_TIMEOUT и тестовой MYSQLX_TEST_CONNECTION_TIMEOUT.
compressionС8.0.20: preferred по умолчанию допускает несжатый канал без общего алгоритма; required в этом случае отказывает; disabled отключает сжатие.
compression-algorithmsС8.0.22: zstd_stream(zstd), lz4_message(lz4), deflate_stream(deflate/zlib). Порядок предпочтения по умолчанию lz4,zstd,deflate зависит от наличия; URI может задать свой список.
Другие формы URIДокументация показывает несколько hosts в квадратных скобках, socket-path в скобках, ssl-mode, ssl-ca и ssl-crl. Для удалённого применения сверяйте правила TLS/URI MySQL; локальный учебный ограничитель эти альтернативы не реализует.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Установленный сеанс даёт реальный первый ответ сервера.

$session = mysql_xdevapi\getSession($config['uri']);
$version = $session->getServerVersion();

Исходные данные, полный файл и ожидаемый результат.

Тот же вход открывает путь к заранее подготовленной схеме; в finally Session закрывается.

$session = mysql_xdevapi\getSession($config['uri']);
$schema = $session->getSchema($config['schema']);

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Не путайте X-порт с classic3306 и не переносите единицы таймаута из другого Connector. Фрагменты URI в справочнике не являются готовыми учётными данными. Символы @/: в компонентах имени/пароля кодируйте; полный URI не включайте в логи. Само наличие DLL не доказывает ответ X Plugin.

mysql_xdevapi\Session::getServerVersionОтличить версию сервера от версии PHP-модуля.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Session::getServerVersion(): int

Отличить версию сервера от версии PHP-модуля.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Целое число версии сервера данного сеанса; например80012 обозначает8.0.12.

УточнениеКак понимать
Что измеряетсяЭто ответ о сервере, а phpversion('mysql_xdevapi') описывает расширение в PHP. Разные процессы и разные номера версий нельзя подменять друг другом.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Первый запуск проверяет требуемую ветку MySQL.

$version = $session->getServerVersion();
$modern = $version >= 80000;

Исходные данные, полный файл и ожидаемый результат.

Квитанция сохраняет обе версии, чтобы повторное исследование использовало тот же контекст.

$runtime = ['server'=>$session->getServerVersion(),
    'extension'=>phpversion('mysql_xdevapi')];

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Метод без параметров не устанавливает и не обновляет сервер. Проверка >=80000 подтверждает основную ветку, но отдельные функции всё равно имеют свои требования к серверу/расширению.

mysql_xdevapi\Schema::createCollectionСоздать место для документов и при необходимости задать проверку формы.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Schema::createCollection(string $name, string $validate = ?): mysql_xdevapi\Collection

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

ВходСмысл
nameИмя создаваемой коллекции внутри выбранной Schema.
validateНеобязательная строка JSON с описанием validation; параметр добавлен в8.0.20.

Результат и отказ

Collection созданной коллекции. В отличие от getCollection это серверное действие.

УточнениеКак понимать
Проверка документаВ JSON-объекте validation можно задать level и schema с type, properties и required. Схема задаёт обязательные поля и их JSON-типы; отклонение документа проверяется при записи. Это отдельная ступень от простого создания пустой коллекции.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Создание пустого каталога возвращает объект, через который ожидаем count0.

$collection = $schema->createCollection($ownName);
$count = $collection->count();

Исходные данные, полный файл и ожидаемый результат.

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

$collection = $schema->createCollection($ownName);
$receipt = $collection->add($document)->execute();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Нельзя считать любой объект Collection доказательством успешного создания. Имя, которое уже занято, не следует освобождать удалением чужих данных. В лаборатории создаются только новые случайные имена, успешно созданные имена регистрируются для cleanup.

mysql_xdevapi\Schema::getCollectionПолучить адресный объект доступа без создания коллекции.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Schema::getCollection(string $name): mysql_xdevapi\Collection

Получить адресный объект доступа без создания коллекции.

ВходСмысл
nameИмя коллекции в этой схеме.

Результат и отказ

Collection для выбранного имени.

УточнениеКак понимать
Разделение действийПолучить handle и создать хранилище — разные операции. Для существования используйте existsInDatabase; для создания — createCollection. Документы читают уже через Collection.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Можно получить адрес ещё не созданной коллекции и отдельно увидеть false.

$handle = $schema->getCollection($ownName);
$before = $handle->existsInDatabase();

Исходные данные, полный файл и ожидаемый результат.

У уже существующего каталога handle используется для открытия конкретной карточки.

$catalog = $schema->getCollection($ownName);
$lamp = $catalog->getOne('LAMP-1');

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

getCollection не является ни выборкой документов, ни проверкой прав на все последующие действия. Существование могло измениться между отдельными командами.

mysql_xdevapi\Collection::existsInDatabaseОтличить существующую коллекцию от одного лишь PHP-объекта.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Collection::existsInDatabase(): bool

Отличить существующую коллекцию от одного лишь PHP-объекта.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

true, если объект указывает на коллекцию в базе, иначе false.

УточнениеКак понимать
Что сервер считает коллекциейPHP Manual отдельно описывает таблицу с колонками doc и _id; начиная с MySQL8.0.21 учитывается третья _json_schema. Добавление иной дополнительной колонки означает, что existsInDatabase больше не распознаёт её как коллекцию.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Тот же handle показывает переход false -> true.

$before = $handle->existsInDatabase();
$created = $schema->createCollection($ownName);
$after = $handle->existsInDatabase();

Исходные данные, полный файл и ожидаемый результат.

В cleanup проверяется обратный переход после удаления только собственной коллекции.

$schema->dropCollection($ownName);
$gone = !$collection->existsInDatabase();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Проверка существования не сообщает число документов и не превращается в блокировку от удаления. Пустая коллекция существует; это проверяется отдельно от count.

mysql_xdevapi\Collection::addПодготовить вставку массива или JSON-документа, сохранив границу отправки.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Collection::add(mixed $document): mysql_xdevapi\CollectionAdd

Подготовить вставку массива или JSON-документа, сохранив границу отправки.

ВходСмысл
documentОдин документ как JSON-строка либо PHP-массив поле=>значение; допускаются несколько документов и смесь этих форм. Пустой массив документом не является.

Результат и отказ

CollectionAdd; его execute возвращает Result с количеством, предупреждениями и generated IDs.

УточнениеКак понимать
_idСервер создаёт уникальный _id автоматически; Manual рекомендует этот вариант. Можно передать свой _id, но повтор уникального ключа приводит к отказу добавления. SKU не заменяет _id автоматически.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Одна адресуемая карточка с числом без кавычек.

$operation = $collection->add(['_id'=>'LAMP-1','price'=>1200]);
$receipt = $operation->execute();

Исходные данные, полный файл и ожидаемый результат.

Две допустимые формы данных в одной операции без заранее назначенных _id.

$receipt = $collection->add(['sku'=>'LED'], '{"sku":"CABLE"}')->execute();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Короткая сигнатура с одним mixed не исчерпывает несколько документированных вариантов вызова. add не означает update и не доказывает запись до execute. Не кодируйте готовую JSON-строку повторно и не считайте PHP-объект Collection самим документом.

mysql_xdevapi\Collection::countУзнать количество документов в коллекции целиком.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Collection::count(): int

Узнать количество документов в коллекции целиком.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Число документов коллекции как int.

УточнениеКак понимать
СмыслСерверная операция аналогична SELECT COUNT(*) для данной коллекции. Это не число настроек CollectionFind, не длина очереди add и не размер страницы limit2.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Новая существующая коллекция даёт0 документов.

$empty = $collection->count();

Исходные данные, полный файл и ожидаемый результат.

Всего5 товаров и не более2 документов страницы — разные числа.

$total = $collection->count();
$page = $collection->find()->limit(2)->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Не подменяйте этим счётчиком количество совпадений произвольного фильтра. Между отдельными чтениями другой клиент может изменить коллекцию; fixture программы исключает такое вмешательство, но реальное приложение — нет.

mysql_xdevapi\Collection::getOneОткрыть конкретный документ по _id либо получить отсутствие.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Collection::getOne(string $id): Document

Открыть конкретный документ по _id либо получить отсутствие.

ВходСмысл
idСтроковое значение _id нужного документа.

Результат и отказ

Данные документа как ассоциативный массив; официальный контракт для отсутствующего _id — null. В PECL mysql_xdevapi8.0.30 обнаружено отклонение, описанное ниже.

УточнениеКак понимать
Сокращение поискаПо смыслу это find('_id = :id')->bind(['id'=>$id])->execute()->fetchOne(). На странице приведена обобщённая запись bind("id", id); для PHP фактическая сигнатура bind принимает массив.
Оговорка ManualСигнатура содержит условное Document, а текст возврата употребляет «collection object». Это не указание создавать новый класс Document: полезные данные — поля прочитанного документа, в отличие от объекта доступа Collection.
Проверенное отклонение8.0.30На PHP8.3.35/ext8.0.30/MySQL8.4.13 отсутствующий getOne вернул внутренний UNDEF: переменная после обычного присваивания не существовала, прямое сравнение вызова с null давало false. Конструкция $doc = $collection->getOne($id) ?? null нормализует отсутствие. getOne получает результат внутреннего fetch_one_from_doc_result без предварительного RETVAL_NULL, тогда как публичный DocResult::fetchOne устанавливает null; в том же опыте find/bind/execute/fetchOne вернул null. Это дефект проверенного расширения, не новый контракт Manual и не обещание поведения других версий.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Карточка и отсутствие различаются явно; ?? null учитывает проверенное отклонение PECL8.0.30.

$lamp = $collection->getOne('LAMP-1');
$missing = $collection->getOne('NO-SUCH') ?? null;

Исходные данные, полный файл и ожидаемый результат.

Реальный ID квитанции связывается с повторно прочитанным документом.

$doc = $collection->getOne($generatedId);
$matches = $doc !== null && $doc['_id'] === $generatedId;

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Проверяйте null до $doc['name']. Совпадение по обычному полю sku — другая задача для find; getOne адресует именно _id.

mysql_xdevapi\Collection::findЗадать условие выбора и получить настраиваемый запрос.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Collection::find(string $search_condition = ?): mysql_xdevapi\CollectionFind

Задать условие выбора и получить настраиваемый запрос.

ВходСмысл
search_conditionНеобязательная строка выражения; отсутствие условия соответствует find('true'). Обычно условие ограничивает подмножество документов; доступны составные условия и связывание параметров.

Результат и отказ

CollectionFind для настройки и дальнейшего execute; это ещё не массив найденных документов.

УточнениеКак понимать
ВыражениеManual описывает допустимое SQL-выражение условия. Здесь используется X DevAPI expression над полями документа, а не произвольная полная команда SELECT. Связывайте переменные значения через bind.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Автор задаёт форму двух условий, значения придут отдельно.

$request = $collection->find('category = :category and price <= :ceiling');

Исходные данные, полный файл и ожидаемый результат.

Полный каталог сознательно ограничен страницей, затем выполняется.

$request = $collection->find()->sort('sku ASC')->limit(2);

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

find без условия выбирает все документы: перед fetchAll большого каталога добавьте осмысленную границу. Пустая выдача после успешного execute отличается от исключения при неправильном запросе.

mysql_xdevapi\CollectionAdd::executeОтправить подготовленное добавление на сервер.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionAdd::execute(): mysql_xdevapi\Result

Отправить подготовленное добавление на сервер.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Result, по которому проверяют состояние операции, в том числе количество затронутых документов.

УточнениеКак понимать
Граница действияВызов execute необходим для отправки CRUD-запроса. До него объект операции сам по себе не подтверждает сохранение.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Программа отдельно наблюдает состояние до отправки и после неё.

$operation = $collection->add($document);
$before = $collection->count();
$receipt = $operation->execute();

Исходные данные, полный файл и ожидаемый результат.

Исполнение нескольких документов возвращает общую квитанцию и реальные ключи.

$receipt = $collection->add($first, $second)->execute();
$ids = $receipt->getGeneratedIds();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Серверный отказ, например конфликт _id, нельзя объявлять успешным нулём. Повтор добавления после неопределённого сетевого исхода требует политики повторов; этот урок не обещает exactly-once.

mysql_xdevapi\CollectionFind::bindПередать пользовательские значения отдельно от выражения поиска.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::bind(array $placeholder_values): mysql_xdevapi\CollectionFind

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

ВходСмысл
placeholder_valuesМассив NAME=>VALUE для одного или нескольких placeholders. В выражении имя пишется :NAME с двоеточием; в ключе массива — NAME.

Результат и отказ

CollectionFind; последующий execute этой операции поиска возвращает DocResult.

УточнениеКак понимать
Тип значенияПередавайте цену числом, категорию строкой. bind передаёт значение, но не заменяет прикладную проверку допустимого диапазона или прав доступа.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Апостроф остаётся частью категории, число сохраняет числовой смысл.

$request->bind(['category'=>"Мастерская O'Neal", 'ceiling'=>1000]);

Исходные данные, полный файл и ожидаемый результат.

Тот же механизм может адресовать серверный ID; getOne представляет короткую форму этой задачи.

$doc = $collection->find('_id = :id')->bind(['id'=>$generatedId])->execute()->fetchOne();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Нельзя связать имя поля либо ASC/DESC как обычное значение. На странице bind возврат от execute обобщён до Result; точный контракт CollectionFind::execute — DocResult.

mysql_xdevapi\CollectionFind::fieldsОставить в ответе поля, нужные экрану.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::fields(string $projection): mysql_xdevapi\CollectionFind

Оставить в ответе поля, нужные экрану.

ВходСмысл
projectionОписание полей: одна строка либо массив строк по тексту Parameters. Если fields не вызван, возвращаются все поля.

Результат и отказ

CollectionFind для дальнейших настроек/исполнения.

УточнениеКак понимать
Сигнатура и описаниеКраткая сигнатура Manual показывает string, но полный текст разрешает array of strings; самостоятельная программа использует именно этот документированный вариант.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Карточка не получает внутреннее поле internal.

$request->fields(['sku','name','price']);

Исходные данные, полный файл и ожидаемый результат.

Контекстное развитие страницы: вместо полных карточек только список артикулов; исходный runnable-урок и данные указаны по ссылке.

$skus = $collection->find()->fields('sku')->sort('sku ASC')->limit(2)->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Проекция не удаляет поля из сохранённого документа и не является изменением его схемы. Не передавайте произвольную строку посетителя как описание полей; сформируйте разрешённую проекцию сами.

mysql_xdevapi\CollectionFind::sortДать выдаче определённый порядок.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::sort(string $sort_expr): mysql_xdevapi\CollectionFind

Дать выдаче определённый порядок.

ВходСмысл
sort_exprОдно или несколько выражений сортировки. ASC — возрастание, DESC — убывание; критерии применяются слева направо, как ORDER BY.

Результат и отказ

CollectionFind, к которому добавляют настройки либо вызывают execute.

УточнениеКак понимать
Несколько критериевManual приводит sort('job desc', 'age asc'): короткая сигнатура показывает один string, пример допускает несколько аргументов, разделённых запятыми.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Каталог сначала показывает доступные по цене товары; sku разрешает равные цены.

$request->sort('price ASC','sku ASC');

Исходные данные, полный файл и ожидаемый результат.

Тот же порядок требуется на каждой странице, иначе offset нельзя осмысленно сравнивать.

$first = $collection->find()->sort('price ASC','sku ASC')->limit(2)->execute();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

При равенстве основного поля нужен дополнительный устойчивый критерий. Порядок полей JSON и порядок документов выдачи — разные вещи. Пользователь выбирает известный вариант сортировки, а не передаёт произвольное выражение.

mysql_xdevapi\CollectionFind::limitОграничить размер выдачи для страницы каталога.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::limit(int $rows): mysql_xdevapi\CollectionFind

Ограничить размер выдачи для страницы каталога.

ВходСмысл
rowsМаксимальное число возвращаемых документов; в уроке положительное целое2.

Результат и отказ

CollectionFind; после execute — DocResult.

УточнениеКак понимать
Максимум, а не обещаниеЕсли совпадений меньше, придёт меньше документов. limit не означает число изменённых документов и не меняет размер коллекции.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Первая страница берёт максимум два товара.

$result = $collection->find()->sort('sku ASC')->limit(2)->execute();

Исходные данные, полный файл и ожидаемый результат.

Если подходящий товар один, limit2 не создаст второй документ.

$short = $collection->find('price <= :ceiling')->bind(['ceiling'=>500])->limit(2)->execute();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Проверяйте размер страницы до вызова: отрицательный/чрезмерный пользовательский ввод не является полезной настройкой. Для страницы нужен также определённый sort; для последующей страницы — offset.

mysql_xdevapi\CollectionFind::offsetПропустить уже показанную часть стабильной выдачи.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::offset(int $position): mysql_xdevapi\CollectionFind

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

ВходСмысл
positionЧисло пропускаемых элементов в сочетании с limit, а не номер страницы.

Результат и отказ

CollectionFind; смещение больше размера результата даёт пустую выдачу.

УточнениеКак понимать
РасчётПри нумерации страниц с1 offset=(page-1)*pageSize; для второй страницы из двух элементов —2. Нулевая начальная позиция означает ничего не пропускать.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Пропуск A,B позволяет получить C,D.

$second = $collection->find()->sort('sku ASC')->limit(2)->offset(2)->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

За концом каталога ожидается [], а не ошибка из-за отсутствия документов.

$empty = $collection->find()->sort('sku ASC')->limit(2)->offset(99)->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Две независимые выдачи с offset не гарантируют отсутствие повторов при конкурентных вставках/удалениях. Большое смещение не обещает дешёвую операцию; урок использует неизменяемые пять документов.

mysql_xdevapi\CollectionFind::executeИсполнить настроенный поиск и получить объект чтения.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\CollectionFind::execute(): mysql_xdevapi\DocResult

Исполнить настроенный поиск и получить объект чтения.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

DocResult для извлечения документов и сведений о состоянии/предупреждениях операции.

УточнениеКак понимать
ЦепочкаДо execute настраиваются find/bind/fields/sort/limit/offset; после execute вызываются методы DocResult. Метод допускает использование внутри цепочки вызовов.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Экран получает набор карточек после всех настроек запроса.

$result = $request->execute();
$documents = $result->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

Тот же объект результата можно читать по одному документу.

$result = $collection->find()->sort('sku ASC')->limit(2)->execute();
$first = $result->fetchOne();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

CollectionFind не является массивом результата. Успешное исполнение с нулём совпадений тоже даёт DocResult, из которого fetchAll возвращает [] либо fetchOne — null.

mysql_xdevapi\DocResult::fetchOneПолучить очередной документ и явно распознать конец.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\DocResult::fetchOne(): array

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

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Ассоциативный массив документа либо null, когда результатов больше нет.

УточнениеКак понимать
Оговорка сигнатурыНа странице в краткой сигнатуре указан array, но Return Values прямо включает null. Условия программы учитывают оба исхода, а не обращаются к полям null.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Цикл читает A и B, затем завершает страницу.

while (($doc = $result->fetchOne()) !== null) {
    $page[] = $doc;
}

Исходные данные, полный файл и ожидаемый результат.

При отсутствующем ключе первый fetchOne уже вернёт null; getOne — короткая форма этой задачи.

$doc = $collection->find('_id = :id')->bind(['id'=>'NO-SUCH'])->execute()->fetchOne();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

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

mysql_xdevapi\DocResult::fetchAllПолучить выбранные документы в виде списка для экрана.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\DocResult::fetchAll(): array

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

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Числовой массив документов, каждый документ — ассоциативный массив; если строк нет — пустой массив.

УточнениеКак понимать
Форма результатаНапример $documents[0]['sku'] — поле первой карточки, но доступ к индексу0 допустим лишь если список непуст. foreach удобен для любого числа карточек.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Из небольшого каталога получается список артикулов.

$documents = $request->execute()->fetchAll();
$skus = array_column($documents, 'sku');

Исходные данные, полный файл и ожидаемый результат.

Пустой список — обычный результат страницы за концом каталога.

$empty = $collection->find()->limit(2)->offset(99)->execute()->fetchAll();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

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

mysql_xdevapi\Result::getGeneratedIdsПолучить настоящие серверные ключи только этой операции.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Result::getGeneratedIds(): array

Получить настоящие серверные ключи только этой операции.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Массив созданных сервером _id последней операции, связанной с этим Result; при их отсутствии пустой массив.

УточнениеКак понимать
ИсточникУникальное поле _id создаёт MySQL. Не путайте ключ документа с AUTO_INCREMENT таблицы или с артикулом SKU; поле _id в коллекции имеет собственную роль.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Каждый возвращённый ключ связан с фактически сохранённой карточкой.

$ids = $receipt->getGeneratedIds();
foreach ($ids as $id) {$readBack[] = $collection->getOne($id);}

Исходные данные, полный файл и ожидаемый результат.

Вторая ситуация: явный ключ, успешная запись, но generatedIds пуст.

$receipt = $collection->add(['_id'=>'MANUAL-1','sku'=>'STAND'])->execute();
$ids = $receipt->getGeneratedIds();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Пустой массив не означает отказ записи: документ с явным _id может успешно добавиться без server-generated IDs. Сохраняйте фактические значения, не используйте ожидаемый пример ID как найденный результат.

mysql_xdevapi\Result::getAffectedItemsCountПрочитать количество затронутых элементов операции.

Точная первая версия метода не всегда указана Manual; стенд mysql_xdevapi8.0.30 · mysql_xdevapi

public function mysql_xdevapi\Result::getAffectedItemsCount(): int

Прочитать количество затронутых элементов операции.

Параметров нет: пустые скобки вызывают действие у уже полученного объекта.

Результат и отказ

Целое число затронутых строк/элементов предыдущей операции, которую представляет Result.

УточнениеКак понимать
ЕдиницыВ нашем add это количество вставленных документов: карточка с price1200 всё равно один элемент. Для других видов записи интерпретацию соотносите с выполненной операцией.

Страница PHP Manual не всегда указывает точную версию появления отдельного метода и не задаёт исчерпывающую таблицу исключений. Здесь используется mysql_xdevapi8.0.30; ошибка аргумента, сервера или транспорта не подменяется значением успешной пустой выдачи. Версионные изменения, прямо указанные документацией, отмечены выше.

Два применения

Реальный Result первой лампы сообщает1.

$added = $receipt->getAffectedItemsCount();

Исходные данные, полный файл и ожидаемый результат.

Первая операция вставила2; после отдельного третьего товара общий count равен3.

$added = $receipt->getAffectedItemsCount();
$total = $collection->count();

Исходные данные, полный файл и ожидаемый результат.

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

Граница применения

Счётчик не содержит сами документы и не означает текущее количество всей коллекции. Не печатайте количество входных массивов как будто это серверная квитанция; вызывайте метод Result.

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

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

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

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

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