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

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

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

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

Глава 130 · После первого каталога и транзакций X DevAPI

MySQL X DevAPI: коллекция, схема и Session без путаницы

Открыть нужную схему, найти коллекции, проследить общий Session, прочитать документы через Table и очистить только свои временные объекты.

Открыть нужный источник и понять результат

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

Путь к одному товару
  1. Session — соединение с MySQL
  2. Schema — выбранная база php_manual_x139
  3. Collection — каталог с документом LED
  4. getOne("LED") — данные товара; getSchema/getSession ведут обратно
Что у нас естьЧто это означаетЧего это ещё не доказывает
Строка имениНазвание, например catalogОбъект создан и доступен
Schema / Collection / TableОбъект PHP для обращения к источникуВ источнике есть данные или нужные права
existsInDatabase() = trueОбъект существует во время проверкиНужный товар найден и объект не изменится
Документ или строка результатаРеально прочитанные данныеДругое последующее чтение даст тот же снимок
Session от коллекцииДоступ к её соединениюЭто отдельная независимая транзакция

Знакомая модель — адресная книга: имя обозначает адрес, объект доступа позволяет к нему обратиться, а успешное чтение приносит содержимое. Это не буквальная модель памяти или хранения. Получение объекта не создаёт базу и не читает автоматически все её документы.

Перед началом нужны первое подключение и создание коллекции, ключи и значения PHP-массива и смысл интерфейса PHP. Текущие методы объясняются в каждом уроке до полной программы. Следующая часть работы с карточками разбирает patch, замену полей и ограниченные порции.

Архив каждого урока содержит example.php, lab.php и README.txt. Программа работает только в подготовленной локальной схеме, создаёт собственные случайные имена mysql143_ и удаляет их в finally. result.html — понятный итог; result.json — исходные значения, типы и список созданных/очищенных объектов; metrics.json — проверки и сводные числа очистки. Пароль и полный URI в отчёт не попадают.

В этом наборе используется существующий профиль PHP 8.3.35, PECL mysql_xdevapi 8.0.30 и MySQL 8.4.13. Особенности выбранного коннектора явно отделены от общего назначения API: в частности, время жизни обёртки Session и предупреждение при повторном dropCollection.

Отличить имя схемы от существующей базы

Страница каталога должна работать с нужной базой, а при ошибке настройки объяснять, почему данных нет. Получение объекта Schema ещё не подтверждает существование базы. Проверим это отдельно, не создавая базу автоматически и не скрывая опечатку в имени.

Путь данных
  1. Настройка содержит имя учебной схемы
  2. getSchema(name) создаёт объект доступа
  3. existsInDatabase() проверяет наличие на сервере
  4. getDefaultSchema() отдельно читает выбор из URI

Разобрать новую операцию

$catalogSchema — переменная с объектом Schema. Стрелка -> вызывает его метод; круглые скобки содержат аргументы. getSchema получает строку имени и возвращает объект, getName без аргументов возвращает это имя, existsInDatabase — true или false. Последний вызов спрашивает о схеме по умолчанию в настройке соединения: результатом может быть null, то есть схема не выбрана. В учебном профиле URI содержит только адрес сервера, а PHPMAN_MYSQLX_SCHEMA задаёт имя отдельно; поэтому getDefaultSchema здесь возвращает null.

$catalogSchema = $session->getSchema('php_manual_x139');
$name = $catalogSchema->getName();
$exists = $catalogSchema->existsInDatabase();
$defaultSchema = $session->getDefaultSchema();

Результат на исходных данных

НаблюдениеРезультат
Настроенная схема существуетда
Имя объекта совпало с настройкойда
Объект несуществующей схемы полученmysql_xdevapi\Schema
Несуществующая схема найдена на серверенет
Схема по умолчанию в учебном URIне задана
Самостоятельная программа и архив
Отличить имя схемы от существующей базыСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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']];

    $configured = $session->getSchema($config['schema']);
    $missingName = x143Name('missing_schema');
    $missing = $session->getSchema($missingName);
    $default = $session->getDefaultSchema();
    $configuredExists = $configured->existsInDatabase();
    $missingExists = $missing->existsInDatabase();
    $namesMatch = $configured->getName() === $config['schema'];
    $missingNamePreserved = $missing->getName() === $missingName;
    $rows = [['Настроенная схема существует',$configuredExists ? 'да' : 'нет'],
        ['Имя объекта совпало с настройкой',$namesMatch ? 'да' : 'нет'],
        ['Объект несуществующей схемы получен',get_debug_type($missing)],
        ['Несуществующая схема найдена на сервере',$missingExists ? 'да' : 'нет'],
        ['Схема по умолчанию в учебном URI',$default === null ? 'не задана' : 'задана']];
    $checks = ['configured_schema_exists'=>$configuredExists && $namesMatch,
        'handle_does_not_create_schema'=>$missing instanceof mysql_xdevapi\Schema && !$missingExists && $missingNamePreserved,
        'default_schema_is_nullable'=>$default === null,
        'schema_implements_database_object'=>$configured instanceof mysql_xdevapi\DatabaseObject];
    $observations = ['configured_name'=>$configured->getName(),'missing_name'=>$missing->getName(),
        'configured_exists'=>$configuredExists,'missing_exists'=>$missingExists,
        'default_schema_type'=>get_debug_type($default),
        'default_schema_name'=>$default instanceof mysql_xdevapi\Schema ? $default->getName() : null];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-schema-handle-and-existence', 'Отличить имя схемы от существующей базы', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Настроенная схема существует — да
Имя объекта совпало с настройкой — да
Объект несуществующей схемы получен — mysql_xdevapi\Schema
Несуществующая схема найдена на сервере — нет
Схема по умолчанию в учебном URI — не задана

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

Схема в MySQL — именованная база с таблицами и коллекциями. Полученный объект похож на адрес на конверте: правильная запись адреса не доказывает, что здание существует. Аналогия заканчивается на доступе: настоящий запрос ещё зависит от соединения и прав. existsInDatabase сообщает состояние во время проверки, а не блокирует базу от удаления другим процессом. Отказ соединения не следует превращать в false и сообщение «базы нет». В рабочем приложении неизвестную схему исправляют в настройке, а не создают по каждому входному имени.

Измените требование

Приложение получило объект Schema с именем store_test, но existsInDatabase вернул false. Можно ли показывать страницу «в каталоге пока нет товаров»?

Разбор следующего шага

Нет: отсутствие базы и пустой каталог — разные состояния. Для первого нужна понятная ошибка настройки, для второго — успешное чтение существующей коллекции с нулём документов. Если defaultSchema равен null, можно выбрать заранее разрешённую схему через getSchema, но нельзя вызывать у null метод getName.

Найти родителей коллекции и сохранить общую транзакцию

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

Путь данных
  1. Collection с товаром LED
  2. getSchema() → родительская Schema
  3. getSession() → объект Session для того же соединения
  4. Черновик CABLE виден до rollback и исчезает после

Разобрать новую операцию

getName возвращает строку; getSchema и getSession возвращают объекты с собственными методами. Три результата нельзя подменять друг другом. У каждого вызова здесь пустые скобки: дополнительных аргументов нет. Полная программа добавляет функцию locateObject: тип SchemaObject означает, что параметр поддерживает получение схемы и унаследованные методы DatabaseObject. Функция возвращает обычный массив с двумя именами. Транзакция — группа изменений до commit или rollback; сначала пример сохраняет LED, затем добавляет CABLE внутри транзакции и откатывает только CABLE. Отсутствие черновика подтверждает отдельный find по его _id: limit(1) ограничивает выборку, fetchAll возвращает массив, и пустой массив [] означает, что документ не найден. Запись $afterRows[0] ?? null безопасно извлекает первый документ либо null.

$schemaOfCatalog = $catalog->getSchema();
$catalogName = $catalog->getName();
$sessionOfCatalog = $catalog->getSession();

Результат на исходных данных

НаблюдениеРезультат
Объект коллекцииmysql_xdevapi\Collection
Родительский объектmysql_xdevapi\Schema
Имя коллекции найдено через интерфейсда
Черновик виден через полученный SessionCABLE
Черновик после rollbackне найден
Ранее сохранённый товарLED
Самостоятельная программа и архив
Найти родителей коллекции и сохранить общую транзакциюСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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']];

function locateObject(mysql_xdevapi\SchemaObject $object): array {
    $parent = $object->getSchema();
    if (!$parent instanceof mysql_xdevapi\Schema) {throw new RuntimeException('Не получена схема объекта.');}
    return ['name'=>$object->getName(), 'schema'=>$parent->getName()];
}

    $name = x143OwnCollection($schema,$owned,'object_graph');
    $catalog = $schema->getCollection($name);
    $catalog->add(['_id'=>'kept','sku'=>'LED','stock'=>5])->execute();
    $parent = $catalog->getSchema();
    if (!$parent instanceof mysql_xdevapi\Schema) {throw new RuntimeException('Не получена родительская схема.');}
    // Keep both wrappers alive until the outer cleanup is complete.
    $fromCollection = $catalog->getSession();
    $fromSchema = $parent->getSession();
    $sessionWrappers = [$fromCollection,$fromSchema];
    $location = locateObject($catalog);
    $fromCollectionSchema = $fromCollection->getSchema($config['schema']);
    $sameCatalog = $fromCollectionSchema->getCollection($name);
    $session->startTransaction();
    $transactionOpen = true;
    try {
        $catalog->add(['_id'=>'draft','sku'=>'CABLE','stock'=>2])->execute();
        $during = $sameCatalog->getOne('draft');
        $fromSchema->rollback();
        $transactionOpen = false;
    } finally {
        if ($transactionOpen) {$session->rollback();}
    }
    $afterRows = $catalog->find('_id = :id')->bind(['id'=>'draft'])->limit(1)->execute()->fetchAll();
    $after = $afterRows[0] ?? null;
    $kept = $catalog->getOne('kept');
    $rows = [['Объект коллекции',get_debug_type($catalog)],['Родительский объект',get_debug_type($parent)],
        ['Имя коллекции найдено через интерфейс',$location['name'] === $name ? 'да' : 'нет'],
        ['Черновик виден через полученный Session',$during['sku'] ?? 'не найден'],
        ['Черновик после rollback',$after === null ? 'не найден' : 'сохранился'],
        ['Ранее сохранённый товар',$kept['sku']]];
    $checks = ['object_graph_matches'=>$location === ['name'=>$name,'schema'=>$config['schema']]
            && $catalog instanceof mysql_xdevapi\SchemaObject && $catalog instanceof mysql_xdevapi\DatabaseObject,
        'wrapper_reads_same_transaction'=>($during['sku'] ?? null) === 'CABLE',
        'wrapper_rollback_is_shared'=>$afterRows === [] && $after === null && $kept['sku'] === 'LED',
        'session_wrappers_are_retained'=>count($sessionWrappers) === 2
            && $fromCollection instanceof mysql_xdevapi\Session && $fromSchema instanceof mysql_xdevapi\Session];
    $observations = ['location'=>$location,'during_transaction'=>$during,'after_rollback_rows'=>$afterRows,'after_rollback'=>$after,'kept'=>$kept,
        'original_session_object_id'=>spl_object_id($session),
        'collection_session_object_id'=>spl_object_id($fromCollection),
        'schema_session_object_id'=>spl_object_id($fromSchema)];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-collection-schema-session', 'Найти родителей коллекции и сохранить общую транзакцию', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Объект коллекции — mysql_xdevapi\Collection
Родительский объект — mysql_xdevapi\Schema
Имя коллекции найдено через интерфейс — да
Черновик виден через полученный Session — CABLE
Черновик после rollback — не найден
Ранее сохранённый товар — LED

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

Новый PHP-объект Session из getSession не означает отдельное независимое подключение. Сравнение объектов через === не проверяет SQL-транзакцию: в примере связь подтверждают видимость черновика и его откат. В выбранном PECL 8.0.30 временная обёртка Session при уничтожении способна закрыть общее соединение. Поэтому сохраняйте полученные Session в переменных до окончания всех запросов и cleanup; избегайте цепочки $catalog->getSession()->sql(...), после которой временный объект теряется. close одного такого Session тоже относится к общему подключению. Для независимой транзакции открывают отдельное соединение явно. Collection::getSchema официально допускает null при невозможности получить схему, поэтому тип результата проверяется. В этом native-профиле getOne отсутствующего ID после rollback дал предупреждение о неинициализированной переменной результата; поэтому отсутствие проверяется реальным массивом fetchAll. Подставить null без запроса было бы недостаточным доказательством отката.

Измените требование

Почему LED остался, хотя rollback вызван через объект, полученный от схемы, а CABLE исчез?

Разбор следующего шага

LED был сохранён до startTransaction. CABLE добавлен после её начала. Полученные Session обращаются к тому же соединению, поэтому rollback отменяет текущую транзакцию независимо от того, через какую его обёртку вызван. Для двух независимых покупателей нужны два отдельных подключения, как в главе о согласовании резервов.

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

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

Путь данных
  1. Schema содержит две коллекции и таблицу журнала
  2. getCollections() → массив имя → Collection
  3. Выбираем только два разрешённых имени
  4. count() каждой коллекции → 2 и 1 документ

Разобрать новую операцию

$collections — PHP-массив: ключ — строка имени, значение — объект Collection. Запись [$catalogName] выбирает значение по ключу; ?? null даёт null при отсутствии ключа. instanceof проверяет тип объекта. count вызывается уже у выбранной коллекции и сообщает количество её документов. В полной программе короткий массив $labels задаёт разрешённые имена и подписи экрана, а foreach обходит эти два элемента, а не документы всех коллекций.

$collections = $schema->getCollections();
$catalog = $collections[$catalogName] ?? null;
if ($catalog instanceof mysql_xdevapi\Collection) {
    $count = $catalog->count();
}

Результат на исходных данных

НаблюдениеРезультат
Действующий каталог: документов2
Архив: документов1
Значения списка являются Collectionmysql_xdevapi\Collection
Обычная таблица журнала существуетда
Журнал попал в список коллекцийнет
Самостоятельная программа и архив
Получить список коллекций, а затем нужные сведенияСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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']];

    $activeName = x143OwnCollection($schema,$owned,'active_catalog');
    $archiveName = x143OwnCollection($schema,$owned,'archive_catalog');
    $tableName = x143OwnTable($session,$schema,$owned,'import_log','(id INT PRIMARY KEY, note VARCHAR(40)) ENGINE=InnoDB');
    $schema->getCollection($activeName)->add(['_id'=>'LED','sku'=>'LED'],['_id'=>'CABLE','sku'=>'CABLE'])->execute();
    $schema->getCollection($archiveName)->add(['_id'=>'OLD','sku'=>'OLD'])->execute();
    $collections = $schema->getCollections();
    $labels = [$activeName=>'Действующий каталог',$archiveName=>'Архив'];
    $listed = [];
    foreach ($labels as $collectionName=>$label) {
        $object = $collections[$collectionName] ?? null;
        if (!$object instanceof mysql_xdevapi\Collection) {throw new RuntimeException('Собственная коллекция отсутствует в списке.');}
        $parent = $object->getSchema();
        $listed[] = ['label'=>$label,'name'=>$object->getName(),'key'=>$collectionName,
            'schema'=>$parent instanceof mysql_xdevapi\Schema ? $parent->getName() : null,
            'documents'=>$object->count(),'type'=>get_debug_type($object)];
    }
    $tablePresent = $schema->getTable($tableName)->existsInDatabase();
    $tableIsCollection = array_key_exists($tableName,$collections);
    $rows = [['Действующий каталог: документов',$listed[0]['documents']],['Архив: документов',$listed[1]['documents']],
        ['Значения списка являются Collection',$listed[0]['type']],
        ['Обычная таблица журнала существует',$tablePresent ? 'да' : 'нет'],
        ['Журнал попал в список коллекций',$tableIsCollection ? 'да' : 'нет']];
    $checks = ['owned_collections_are_listed'=>count($listed) === 2 && $listed[0]['name'] === $activeName && $listed[1]['name'] === $archiveName,
        'names_are_array_keys'=>$listed[0]['name'] === $listed[0]['key'] && $listed[1]['name'] === $listed[1]['key'],
        'counts_are_documents_not_objects'=>$listed[0]['documents'] === 2 && $listed[1]['documents'] === 1,
        'table_is_not_collection'=>$tablePresent && !$tableIsCollection,
        'parents_match'=>$listed[0]['schema'] === $config['schema'] && $listed[1]['schema'] === $config['schema']];
    $observations = ['owned_collections'=>$listed,'owned_table_name'=>$tableName,
        'table_exists'=>$tablePresent,'table_is_listed_as_collection'=>$tableIsCollection];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-list-owned-collections', 'Получить список коллекций, а затем нужные сведения', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Действующий каталог: документов — 2
Архив: документов — 1
Значения списка являются Collection — mysql_xdevapi\Collection
Обычная таблица журнала существует — да
Журнал попал в список коллекций — нет

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

Обычная таблица и коллекция классифицируются сервером по структуре. Распознавание таблицы с вручную добавленными столбцами зависит от её структуры и версии сервера/коннектора: это отдельно разбиралось в реальном вопросе ниже. В этом примере коллекции создаются штатно, а их внутренняя структура не меняется; для задач каталога используйте поддерживаемые индексы и проверку схемы. Порядок getCollections не следует использовать как порядок интерфейса: задайте его явно. Проверка по списку — снимок состояния, затем чтение всё равно может завершиться ошибкой. В общей схеме могут быть чужие коллекции; пример выводит только собственные точные имена и никогда не удаляет весь полученный список.

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

Измените требование

В массиве getCollections три элемента, а в каталоге 1000 товаров. Какое число означает три?

Разбор следующего шага

Три — число объектов коллекций в полученном массиве. Количество документов получают у нужной Collection через count или специализированный запрос. Для списка товаров задайте fields/условие/порядок/limit, не обходите все коллекции и не объединяйте их содержимое ради одного экрана.

Прочитать один каталог через Collection и Table

Товары уже хранятся документами, но для отчёта нужны отдельные строки с артикулом и остатком. Можно получить Table для той же коллекции. Проверим, что это второй способ чтения одних данных, а не новая копия каталога.

Путь данных
  1. Один документ LED со stock=5
  2. Collection читает JSON-поля
  3. getCollectionAsTable() открывает ту же коллекцию как Table
  4. Изменили stock на 4 → оба способа читают 4

Разобрать новую операцию

getCollectionAsTable принимает имя существующей коллекции и возвращает Table. На стороне хранения doc — JSON-документ, _id — его идентификатор; это не отдельный SQL-столбец для каждого поля JSON. Минимальный фрагмент показывает одну строку с doc. Полная программа делает более точную проекцию: JSON_EXTRACT выбирает путь $.sku, JSON_UNQUOTE получает текст без JSON-кавычек, CAST AS UNSIGNED переводит заведомо целый учебный stock в число. AS задаёт имя поля в результате. Условие по _id и bind выбирают один товар до передачи данных в PHP.

$table = $schema->getCollectionAsTable($catalogName);
$result = $table->select(['_id', 'doc'])->where('_id = :id')->bind(['id' => 'LED'])->execute();
$row = $result->fetchOne();

Результат на исходных данных

НаблюдениеРезультат
Исходный документ: SKULED
Исходный документ: остаток5
Table до изменения: остаток5
Table после изменения: остаток4
Collection после изменения: остаток4
Соседний товар: остаток2
Самостоятельная программа и архив
Прочитать один каталог через Collection и TableСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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 = x143OwnCollection($schema,$owned,'table_bridge');
    $catalog = $schema->getCollection($name);
    $catalog->add(['_id'=>'LED','sku'=>'LED','stock'=>5],['_id'=>'CABLE','sku'=>'CABLE','stock'=>2])->execute();
    $table = $schema->getCollectionAsTable($name);
    $before = $catalog->getOne('LED');
    $projection = ["JSON_UNQUOTE(JSON_EXTRACT(doc, '$.sku')) AS sku",
        "CAST(JSON_UNQUOTE(JSON_EXTRACT(doc, '$.stock')) AS UNSIGNED) AS stock"];
    $tableBefore = $table->select($projection)->where('_id = :id')->bind(['id'=>'LED'])->execute()->fetchOne();
    $catalog->modify('_id = :id')->set('stock',4)->bind(['id'=>'LED'])->execute();
    $tableAfter = $table->select($projection)->where('_id = :id')->bind(['id'=>'LED'])->execute()->fetchOne();
    $after = $catalog->getOne('LED');
    $other = $catalog->getOne('CABLE');
    $rows = [['Исходный документ: SKU',$before['sku']],['Исходный документ: остаток',$before['stock']],
        ['Table до изменения: остаток',$tableBefore['stock']],['Table после изменения: остаток',$tableAfter['stock']],
        ['Collection после изменения: остаток',$after['stock']],['Соседний товар: остаток',$other['stock']]];
    $checks = ['same_collection_name'=>$table->getName() === $catalog->getName(),
        'projection_matches_document'=>$tableBefore['sku'] === 'LED' && $tableBefore['stock'] === 5 && $before['stock'] === 5,
        'table_sees_document_change'=>$tableAfter['stock'] === 4 && $after['stock'] === 4,
        'neighbor_is_unchanged'=>$other['stock'] === 2,
        'bridge_returns_table'=>$table instanceof mysql_xdevapi\Table];
    $observations = ['collection_type'=>get_debug_type($catalog),'table_type'=>get_debug_type($table),
        'before_document'=>$before,'before_projection'=>$tableBefore,'after_document'=>$after,'after_projection'=>$tableAfter,
        'stock_sql_type'=>get_debug_type($tableAfter['stock']),'neighbor'=>$other];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-collection-table-bridge', 'Прочитать один каталог через Collection и Table', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Исходный документ: SKU — LED
Исходный документ: остаток — 5
Table до изменения: остаток — 5
Table после изменения: остаток — 4
Collection после изменения: остаток — 4
Соседний товар: остаток — 2

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

Этот метод не переносит данные и не создаёт новую таблицу. Два объекта PHP обращаются к одному источнику; согласованность повторных чтений зависит от транзакции и её уровня изоляции. CAST в примере применён к собственным корректным целым данным; произвольный ввод сначала проверяют, а сообщения преобразования нельзя игнорировать. Не добавляйте столбцы к внутренней таблице коллекции ради каждого JSON-поля. Для часто используемых фильтров выбирайте подходящий индекс коллекции. Не выгружайте все doc в PHP, если экрану нужны два поля одной записи.

Вопрос возникает, когда привычный путь «база → таблица → строки» встречается с термином Collection. Наша программа показывает оба API к одному источнику и реальное изменение остатка, чтобы различие не оставалось только определением. Обсуждение: Чем коллекция отличается от таблицы MySQL.

Измените требование

Почему после set("stock",4) через Collection новый остаток появился в Table без дополнительной синхронизации?

Разбор следующего шага

Table — объект доступа к той же коллекции. Мы создали только одну коллекцию и не делали копию данных. Запрос Table повторно прочитал изменённый JSON-путь. Если нужна независимая копия для отчёта на фиксированный момент, это уже отдельный процесс или транзакционный снимок с явно выбранной политикой обновления.

Отделить выбранный столбец от значения фильтра

В отчёте человек выбирает «цена» или «остаток», а поиск идёт по названию товара с апострофом. Здесь есть два разных входа: имя SQL-столбца и текстовое значение. Покажем, как получить нужное число, не превращая каждый вход в часть синтаксиса SQL.

Путь данных
  1. Выбор price → разрешённое имя price_cents
  2. quoteName оформляет идентификатор
  3. Название Maker’s lamp передаётся через bind
  4. SELECT возвращает 1250 копеек одной строки

Разобрать новую операцию

Идентификатор — имя таблицы, схемы или столбца. quoteName принимает строку имени и возвращает корректно оформленную SQL-строку идентификатора с экранированием внутренних обратных кавычек. Значение — например название товара — передают через placeholder ? и bind. В полном сценарии chooseReportField преобразует ключ интерфейса price в заранее разрешённое имя price_cents. Проверка array_key_exists отличает известный вариант от любого другого. Возвращённая строка используется только как имя столбца; апостроф в названии не требует ручной замены.

$quotedField = $session->quoteName('price_cents');
$value = $session->sql('SELECT ? AS title')->bind("Maker's lamp")->execute()->fetchOne();

Результат на исходных данных

НаблюдениеРезультат
Разрешённый столбецprice_cents
Цена найденной лампы в копейках1250
Найдено строк1
Неизвестный вариант отклонёнда
Обратная кавычка внутри имени`price``retail`
Если передать имя как значениеprice_cents
Самостоятельная программа и архив
Отделить выбранный столбец от значения фильтраСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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']];

function chooseReportField(string $choice): string {
    $allowed = ['price'=>'price_cents','stock'=>'stock'];
    if (!array_key_exists($choice,$allowed)) {
        throw new InvalidArgumentException('Неизвестный вариант отчёта.');
    }
    return $allowed[$choice];
}

    $name = x143OwnTable($session,$schema,$owned,'report_choice',
        '(id INT PRIMARY KEY, title VARCHAR(80) NOT NULL, price_cents INT NOT NULL, stock INT NOT NULL) ENGINE=InnoDB');
    $catalog = $schema->getTable($name);
    $catalog->insert(['id','title','price_cents','stock'])->values([1,"Maker's lamp",1250,5])->values([2,'Cable',300,2])->execute();
    $field = chooseReportField('price');
    $qualified = $session->quoteName($schema->getName()).'.'.$session->quoteName($name);
    $sql = 'SELECT '.$session->quoteName($field).' AS selected_value FROM '.$qualified
        .' WHERE '.$session->quoteName('title').' = ?';
    $found = $session->sql($sql)->bind("Maker's lamp")->execute()->fetchAll();
    $rejected = false;
    try {chooseReportField('password_hash');}
    catch (InvalidArgumentException $error) {$rejected = true;}
    $quoted = $session->quoteName('price`retail');
    $literal = $session->sql('SELECT ? AS selected_value')->bind('price_cents')->execute()->fetchOne();
    $rows = [['Разрешённый столбец',$field],['Цена найденной лампы в копейках',$found[0]['selected_value']],
        ['Найдено строк',count($found)],['Неизвестный вариант отклонён',$rejected ? 'да' : 'нет'],
        ['Обратная кавычка внутри имени',$quoted],['Если передать имя как значение',$literal['selected_value']]];
    $checks = ['allowlist_selects_expected_field'=>$field === 'price_cents',
        'quoted_value_is_bound'=>count($found) === 1 && $found[0]['selected_value'] === 1250,
        'unknown_identifier_is_rejected'=>$rejected,
        'backtick_is_escaped'=>$quoted === '`price``retail`',
        'placeholder_represents_value'=>$literal['selected_value'] === 'price_cents'];
    $observations = ['selected_field'=>$field,'sql_template'=>$sql,'matched_rows'=>$found,
        'invalid_choice_rejected'=>$rejected,'quoted_identifier'=>$quoted,'bound_literal'=>$literal];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-identifier-and-value', 'Отделить выбранный столбец от значения фильтра', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Разрешённый столбец — price_cents
Цена найденной лампы в копейках — 1250
Найдено строк — 1
Неизвестный вариант отклонён — да
Обратная кавычка внутри имени — `price``retail`
Если передать имя как значение — price_cents

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

quoteName не решает, какие поля пользователь вправе видеть. Даже корректно заключённое в кавычки имя password_hash может раскрыть нежелательные данные — поэтому сначала allowlist. Placeholder не подставляет имя столбца: SELECT ? с переданным price_cents возвращает сам текст price_cents. Схему и таблицу цитируют по отдельности и соединяют точкой; quoteName("schema.table") сделает одно имя с точкой. Для ASC/DESC нужен отдельный ограниченный выбор ключевого слова, а не quoteName. Не выводите сырые SQL-ошибки на публичную страницу; их диагностические детали предназначены журналу.

Автор динамического запроса пытался привязать имя таблицы, имя поля и искомое значение одним способом и получил неверный результат. Здесь собственный пример отдельно выбирает разрешённый идентификатор и привязывает значение; PDO-синтаксис не переносится в X DevAPI. Обсуждение: Почему placeholder не выбирает столбец или таблицу.

Измените требование

Как добавить в интерфейс выбор «остаток», не разрешая пользователю вводить произвольный SQL-столбец?

Разбор следующего шага

В таблице разрешений уже есть stock → stock. Передайте ключ stock в chooseReportField: SQL получит только разрешённое имя, а результатом для лампы будет 5. Имена бизнес-вариантов удобно отделять от SQL-имён: при переименовании колонки меняется одна запись карты, а пользовательский интерфейс сохраняет прежний ключ.

Удалить временную коллекцию и сохранить соседний каталог

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

Путь данных
  1. Две собственные коллекции: импорт и каталог
  2. В owned записано точное имя завершённого импорта
  3. dropCollection удаляет только этот объект
  4. Повторная проверка: импорт отсутствует, LED остаётся

Разобрать новую операцию

dropCollection получает строку имени коллекции в данной схеме. Метод удаляет объект целиком вместе с документами; для удаления отдельных документов используют Collection::remove. Возвращаемый bool — результат операции, а отдельный existsInDatabase показывает наличие после неё. Переменная с прежним Collection может остаться в PHP после удаления: она не восстанавливает объект на сервере. В самостоятельной программе имя проверяется по точной паре type/name из owned. Повторный вызов в выбранном коннекторе возвращает false и PHP-предупреждение E_WARNING с серверным кодом 1051. Временный error handler собирает только это ожидаемое сообщение и восстанавливается через finally; исключение и предупреждение — разные механизмы.

$existsBefore = $schema->getCollection($temporaryName)->existsInDatabase();
$removed = $schema->dropCollection($temporaryName);
$existsAfter = $schema->getCollection($temporaryName)->existsInDatabase();

Результат на исходных данных

НаблюдениеРезультат
Временная коллекция до удаленияесть
Результат первого dropCollectiontrue
Временная коллекция после удалениянет
Результат повторного удаленияfalse
Код предупреждения повторного удаления1051
Соседний каталог сохранёнда
Товар соседнего каталогаLED
Остаток соседнего товара5
Самостоятельная программа и архив
Удалить временную коллекцию и сохранить соседний каталогСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__.'/lab.php';

$config = x143Config();
$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']];

    $temporaryName = x143OwnCollection($schema,$owned,'finished_import');
    $keptName = x143OwnCollection($schema,$owned,'kept_catalog');
    $temporary = $schema->getCollection($temporaryName);
    $kept = $schema->getCollection($keptName);
    $temporary->add(['_id'=>'import1','status'=>'completed'])->execute();
    $kept->add(['_id'=>'LED','sku'=>'LED','stock'=>5])->execute();
    $before = $temporary->existsInDatabase();
    $exactOwned = in_array(['type'=>'COLLECTION','name'=>$temporaryName],$owned,true);
    if (!$exactOwned) {throw new RuntimeException('Удаляемый объект не принадлежит этому примеру.');}
    $firstReturn = $schema->dropCollection($temporaryName);
    $after = $temporary->existsInDatabase();
    $dropWarnings = [];
    set_error_handler(function (int $severity, string $message) use (&$dropWarnings): bool {
        if ($severity === E_WARNING && str_contains($message,'[1051]')) {
            $dropWarnings[] = ['severity'=>$severity,'message'=>$message,'server_code'=>1051];
            return true;
        }
        return false;
    });
    try {$secondReturn = $schema->dropCollection($temporaryName);}
    finally {restore_error_handler();}
    $neighbor = $kept->getOne('LED');
    $rows = [['Временная коллекция до удаления',$before ? 'есть' : 'нет'],
        ['Результат первого dropCollection',$firstReturn ? 'true' : 'false'],
        ['Временная коллекция после удаления',$after ? 'есть' : 'нет'],
        ['Результат повторного удаления',$secondReturn === false ? 'false' : 'другой'],
        ['Код предупреждения повторного удаления',$dropWarnings[0]['server_code'] ?? null],
        ['Соседний каталог сохранён',$kept->existsInDatabase() ? 'да' : 'нет'],
        ['Товар соседнего каталога',$neighbor['sku']],['Остаток соседнего товара',$neighbor['stock']]];
    $checks = ['only_owned_collection_is_dropped'=>$exactOwned && $before && !$after,
        'drop_returns_success'=>$firstReturn === true,
        'neighbor_is_preserved'=>$kept->existsInDatabase() && $neighbor['sku'] === 'LED' && $neighbor['stock'] === 5,
        'repeated_drop_does_not_recreate'=>$temporary->existsInDatabase() === false,
        'repeated_drop_reports_absence'=>$secondReturn === false && count($dropWarnings) === 1 && $dropWarnings[0]['server_code'] === 1051];
    $observations = ['dropped_name'=>$temporaryName,'first_return'=>$firstReturn,'first_return_type'=>get_debug_type($firstReturn),
        'second_return'=>$secondReturn,'second_return_type'=>get_debug_type($secondReturn),'second_warnings'=>$dropWarnings,
        'kept_name'=>$keptName,'neighbor'=>$neighbor,'before'=>$before,'after'=>$after];

} finally {
    try {
        if ($schema instanceof mysql_xdevapi\Schema) {
            $removed = x143Cleanup($schema, $owned);
        }
    } finally {
        $session->close();
    }
}

x143Report('mysql143-x-owned-collection-lifecycle', 'Удалить временную коллекцию и сохранить соседний каталог', $rows, $checks, $observations, $runtime, $owned, $removed);
Ожидаемый результат
Временная коллекция до удаления — есть
Результат первого dropCollection — true
Временная коллекция после удаления — нет
Результат повторного удаления — false
Код предупреждения повторного удаления — 1051
Соседний каталог сохранён — да
Товар соседнего каталога — LED
Остаток соседнего товара — 5

CLI-программа использует отдельную учебную схему, создаёт только собственные объекты, выполняет запросы, сохраняет readback и очищает созданные объекты. result.html показывает итог, result.json — настоящие данные и типы. Это не HTTP-обработчик.

Таблица фактического запуска · Исходные ответы и наблюдения в JSON.

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

DDL-операцию удаления коллекции нельзя преподавать как изменение, которое гарантированно вернёт rollback. Для учебного примера создаются только новые случайные имена и удаляются только они; рабочие коллекции так не очищают. Не запускайте drop в цикле по всему getCollections и не доверяйте одному совпадению префикса. Между проверкой exists и удалением другой процесс может изменить состояние, поэтому учитывайте return/исключение самой операции. Общий finally снова проверяет собственные имена и корректно пропускает уже удалённую коллекцию.

Измените требование

Нужно очистить документы завершённого импорта, но сохранить саму коллекцию и её индексы. Подойдёт ли dropCollection?

Разбор следующего шага

Нет: он удалит коллекцию целиком. Используйте условное Collection::remove с явно выбранными документами и выполните execute, затем проверьте количество и оставшиеся записи. Если коллекция нужна другому процессу, её жизненным циклом должен управлять согласованный процесс обслуживания, а не случайный обработчик запроса.

Выбрать метод доступа к объекту

ИнструментЗадача
DatabaseObjectПозволяет общей функции получить сведения о разных объектах базы, не предполагая наличие документов или строк у каждого из них.
DatabaseObject::existsInDatabaseПроверяет наличие объекта базы, на который указывает PHP-объект доступа.
DatabaseObject::getNameВозвращает имя, связанное с объектом доступа: для Schema — имя схемы, для Collection — коллекции, для Table — таблицы или представления.
DatabaseObject::getSessionДаёт доступ к сеансу от уже переданной схемы, коллекции или таблицы.
SchemaObjectПозволяет одной функции работать с местоположением Collection и Table.
SchemaObject::getSchemaВозвращает схему, к которой относится объект, реализующий SchemaObject.
Collection::getNameПолучает имя коллекции от её объекта.
Collection::getSchemaВозвращает родительскую схему выбранной коллекции.
Collection::getSessionПозволяет коду, получившему только Collection, обратиться к её Session.
Schema::existsInDatabaseПроверяет существование схемы, к которой относится текущий объект Schema.
Schema::getCollectionAsTableОткрывает коллекцию через табличный API.
Schema::getCollectionsПолучает список коллекций данной схемы.
Schema::getNameВозвращает строковое имя базы от объекта Schema.
Schema::getSessionПолучает Session от уже известной Schema.
Schema::dropCollectionУдаляет коллекцию целиком из схемы.
Session::getDefaultSchemaЧитает выбор схемы, обычно заданный в URI подключения.
Session::getSchemaПолучает Schema через существующий Session.
Session::quoteNameЭкранирует SQL-имя и добавляет необходимые кавычки.

От адреса каталога к полезному изменению

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

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

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

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

mysql_xdevapi\DatabaseObjectПозволяет общей функции получить сведения о разных объектах базы, не предполагая наличие документов или строк у каждого из них.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

interface mysql_xdevapi\DatabaseObject { public function existsInDatabase(): bool; public function getName(): string; public function getSession(): mysql_xdevapi\Session; }

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

Запись, параметры и результат

interface mysql_xdevapi\DatabaseObject { public function existsInDatabase(): bool; public function getName(): string; public function getSession(): mysql_xdevapi\Session; }

Это описание интерфейса, а не вызов с аргументами. Передайте функции уже полученную Schema, Collection или Table.

Общий договор: узнать имя, существование и связанный Session. Интерфейс сам не создаёт объект в MySQL.

Позволяет общей функции получить сведения о разных объектах базы, не предполагая наличие документов или строк у каждого из них. Официальный раздел называется interface, хотя synopsis печатает class с abstract public методами; matching PECL 8.0.30 регистрирует настоящий интерфейс. В нём три метода без аргументов: existsInDatabase(): bool, getName(): string, getSession(): Session. Schema реализует DatabaseObject; Collection и Table получают этот договор через SchemaObject. Тип доступен с PECL mysql_xdevapi 8.0.11. new DatabaseObject не является способом открыть базу.

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

Одинаковая строка состояния схемы и коллекции

Получаем имя и наличие для разных типов; false не означает «в объекте ноль записей».

function objectState(mysql_xdevapi\DatabaseObject $object): array {
    return ['name' => $object->getName(), 'exists' => $object->existsInDatabase()];
}

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

Получить сеанс от переданного объекта

Сеанс остаётся в переменной. Новый объект PHP не обещает отдельное подключение.

$objectSession = $object->getSession();
$schemaForReport = $objectSession->getSchema($configuredSchemaName);

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

Границы и связанные действия

Не вызывайте count/find/select на произвольном DatabaseObject: этих методов в данном договоре нет. getSession возвращает объект, а не строку имени, несмотря на краткую подпись в Manual. Полученную обёртку сохраняют до конца работы.

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

mysql_xdevapi\DatabaseObject::existsInDatabaseПроверяет наличие объекта базы, на который указывает PHP-объект доступа.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

abstract public mysql_xdevapi\DatabaseObject::existsInDatabase(): bool

Проверяет наличие объекта базы, на который указывает PHP-объект доступа.

Запись, параметры и результат

abstract public mysql_xdevapi\DatabaseObject::existsInDatabase(): bool

Аргументов нет; проверяется объект, у которого вызван метод.

true, если соответствующий объект существует; false, если отсутствует.

Проверяет наличие объекта базы, на который указывает PHP-объект доступа. Интерфейс задаёт общий метод для Schema, Collection и Table, но конкретный объект определяет, что именно проверяется. Получение handle не равно созданию объекта. Пустая коллекция существует, даже когда не содержит документов; отсутствующая коллекция может быть представлена PHP-объектом с именем.

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

Понятная ошибка настройки

Останавливаем открытие каталога до чтения документов; не показываем ложное «товаров нет».

if (!$catalogSchema->existsInDatabase()) {
    throw new RuntimeException('Настроенная схема отсутствует.');
}

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

Убедиться, что временный объект исчез

Сохранившаяся PHP-переменная не удерживает коллекцию на сервере.

$schema->dropCollection($temporaryName);
$stillExists = $temporary->existsInDatabase();

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

Границы и связанные действия

Проверка не блокирует объект от конкурентного удаления. Ошибка соединения или прав требует обработки самой операции и не должна безусловно превращаться в ответ false. Проверяйте нужный тип: Collection и произвольная Table не взаимозаменяемы.

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

mysql_xdevapi\DatabaseObject::getNameВозвращает имя, связанное с объектом доступа: для Schema — имя схемы, для Collection — коллекции, для Table — таблицы или представления.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

abstract public mysql_xdevapi\DatabaseObject::getName(): string

Возвращает имя, связанное с объектом доступа: для Schema — имя схемы, для Collection — коллекции, для Table — таблицы или представления.

Запись, параметры и результат

abstract public mysql_xdevapi\DatabaseObject::getName(): string

Аргументов нет.

Имя данного объекта базы как строка.

Возвращает имя, связанное с объектом доступа: для Schema — имя схемы, для Collection — коллекции, для Table — таблицы или представления. Это удобно для отчёта о выбранном источнике и проверки настройки. Официальная страница содержит предупреждение о неполноте документации; указаны безаргументная сигнатура и строковый результат.

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

Показать источник отчёта

На экране видно имя выбранного источника, а специальные символы не становятся HTML.

$sourceName = $object->getName();
echo htmlspecialchars($sourceName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

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

Сопоставить handle с настройкой

Имя проверено отдельно от существования схемы; это два разных вопроса.

$matchesConfiguration = $catalogSchema->getName() === $configuredSchemaName;

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

Границы и связанные действия

Имя не доказывает существование, число записей или право на удаление. Возвращённая строка ещё не оформлена как SQL-идентификатор; для SQL нужен quoteName и разрешённый набор имён. HTML-вывод экранируют.

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

mysql_xdevapi\DatabaseObject::getSessionДаёт доступ к сеансу от уже переданной схемы, коллекции или таблицы.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

abstract public mysql_xdevapi\DatabaseObject::getSession(): mysql_xdevapi\Session

Даёт доступ к сеансу от уже переданной схемы, коллекции или таблицы.

Запись, параметры и результат

abstract public mysql_xdevapi\DatabaseObject::getSession(): mysql_xdevapi\Session

Аргументов нет.

Объект Session, связанный с объектом базы.

Даёт доступ к сеансу от уже переданной схемы, коллекции или таблицы. Подпись официальной страницы говорит о «session name», но описание и return указывают Session. Это объект для SQL, транзакций и доступа к схемам, а не строковое имя и не идентификатор сессии.

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

Восстановить путь к известной схеме

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

$objectSession = $object->getSession();
$schemaForReport = $objectSession->getSchema($configuredSchemaName);

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

Откатить общую группу изменений

Откат относится к соединению, а не исключительно к тому PHP-объекту, у которого получена обёртка.

$objectSession = $object->getSession();
// Изменения уже выполнены внутри активной транзакции этого соединения.
$objectSession->rollback();

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

Границы и связанные действия

Не считайте обёртку отдельным соединением и не закрывайте её посреди работы исходного Session. В PECL 8.0.30 храните её в переменной до завершения запросов и очистки: уничтожение временной обёртки может закрыть общее соединение.

Общая транзакция и время жизни Session связывает объектную модель с наблюдаемым откатом. Отдельные соединения для согласования резервов нужны для независимых участников.

mysql_xdevapi\SchemaObjectПозволяет одной функции работать с местоположением Collection и Table.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

interface mysql_xdevapi\SchemaObject extends mysql_xdevapi\DatabaseObject { public function getSchema(): mysql_xdevapi\Schema; }

Позволяет одной функции работать с местоположением Collection и Table.

Запись, параметры и результат

interface mysql_xdevapi\SchemaObject extends mysql_xdevapi\DatabaseObject { public function getSchema(): mysql_xdevapi\Schema; }

Тип параметра для существующего объекта, принадлежащего схеме; сам интерфейс не создаётся через new.

Добавляет getSchema к договору DatabaseObject: объект знает свою родительскую схему.

Позволяет одной функции работать с местоположением Collection и Table. Она получает имя объекта через унаследованный getName и объект родительской схемы через getSchema. В официальном synopsis напечатано class implements DatabaseObject, однако heading и исходник расширения определяют интерфейс, наследующий DatabaseObject. Доступен с PECL 8.0.11. Schema сама реализует DatabaseObject, а не является вложенной SchemaObject внутри себя.

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

Общая подпись для коллекции и таблицы

Функция сообщает местоположение, не смешивая документы и реляционные строки.

function location(mysql_xdevapi\SchemaObject $object): array {
    $parent = $object->getSchema();
    if (!$parent instanceof mysql_xdevapi\Schema) {
        throw new RuntimeException('Нет родительской схемы.');
    }
    return ['name' => $object->getName(), 'schema' => $parent->getName()];
}

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

Убедиться, что два API относятся к одному источнику

В пределах одного известного подключения сравниваем пару имя схемы + имя объекта. На разных серверах даже такая пара может совпадать; PHP-идентичность обёрток здесь не требуется.

$collectionSchema = $catalog->getSchema();
$tableSchema = $table->getSchema();
$sameSource = $collectionSchema instanceof mysql_xdevapi\Schema
    && $tableSchema instanceof mysql_xdevapi\Schema
    && $collectionSchema->getName() === $tableSchema->getName()
    && $catalog->getName() === $table->getName();

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

Границы и связанные действия

Не обещайте find любому SchemaObject: у Table другой API чтения. Для Collection описание getSchema допускает null при невозможности получить родителя; проверяйте конкретный результат, прежде чем вызвать у него методы.

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

mysql_xdevapi\SchemaObject::getSchemaВозвращает схему, к которой относится объект, реализующий SchemaObject.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

abstract public mysql_xdevapi\SchemaObject::getSchema(): mysql_xdevapi\Schema

Возвращает схему, к которой относится объект, реализующий SchemaObject.

Запись, параметры и результат

abstract public mysql_xdevapi\SchemaObject::getSchema(): mysql_xdevapi\Schema

Аргументов нет; родитель определяется по объекту вызова.

Родительский объект Schema.

Возвращает схему, к которой относится объект, реализующий SchemaObject. Сначала получают сам Schema, затем при необходимости его строковое имя через getName. В официальном примере ошибочно показан Session::getSchema с аргументом имени; это другой способ получения Schema. Текущий интерфейсный метод имени не принимает.

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

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

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

$parent = $catalog->getSchema();
$schemaName = $parent instanceof mysql_xdevapi\Schema ? $parent->getName() : null;

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

Выбрать соседнюю коллекцию в том же родителе

Разрешённое имя архива задано приложением; получение handle ещё требует проверки существования.

$parent = $catalog->getSchema();
if ($parent instanceof mysql_xdevapi\Schema) {
    $archive = $parent->getCollection($approvedArchiveName);
}

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

Границы и связанные действия

Не передавайте имя в getSchema коллекции: оно уже известно объекту. При неизвестной схеме у Session имя требуется, у SchemaObject — нет. Учитывайте документированную возможность null для конкретного Collection::getSchema.

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

mysql_xdevapi\Collection::getNameПолучает имя коллекции от её объекта.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Collection::getName(): string

Получает имя коллекции от её объекта.

Запись, параметры и результат

public mysql_xdevapi\Collection::getName(): string

Аргументов нет.

Строка имени коллекции.

Получает имя коллекции от её объекта. Например, если Schema создала коллекцию people, getName вернёт people. Метод не возвращает имя схемы, список документов или _id отдельного товара. Он полезен, когда функция получила Collection, а исходная строка имени находится в другом участке программы.

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

Подпись выбранного каталога

Два вызова дают имя коллекции и её родителя для отчёта.

$catalogName = $catalog->getName();
$parent = $catalog->getSchema();

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

Сверить имя объекта с ключом списка

Каждое значение — Collection, а ключ — её имя; документы находятся глубже.

foreach ($schema->getCollections() as $name => $collection) {
    $keyMatchesName = $name === $collection->getName();
}

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

Границы и связанные действия

Совпадение имён в разных схемах не делает коллекции одним источником. Для идентификации добавляйте имя Schema. Для удаления недостаточно одного имени: нужен точный список владения или разрешённая административная операция.

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

mysql_xdevapi\Collection::getSchemaВозвращает родительскую схему выбранной коллекции.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Collection::getSchema(): ?mysql_xdevapi\Schema

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

Запись, параметры и результат

public mysql_xdevapi\Collection::getSchema(): ?mysql_xdevapi\Schema

Аргументов нет.

Schema при успешном получении; официальное описание допускает null, если объект схемы не удалось получить.

Возвращает родительскую схему выбранной коллекции. Это готовый объект, с которым можно получить имя или обратиться к другой разрешённой коллекции. Synopsis PHP Manual использует нестандартное «Schema Object», а раздел Return Values уточняет возможность null. Здесь запись ?Schema показывает эту описанную границу; она не выдаётся за буквальную Reflection-сигнатуру расширения.

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

Показать полный путь каталога

Путь — подпись для человека, не готовый SQL-идентификатор.

$parent = $catalog->getSchema();
if ($parent instanceof mysql_xdevapi\Schema) {
    $location = $parent->getName() . '/' . $catalog->getName();
}

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

Получить Table для того же каталога

Новая обёртка Table читает ту же коллекцию, без копирования документов.

$parent = $catalog->getSchema();
if ($parent instanceof mysql_xdevapi\Schema) {
    $table = $parent->getCollectionAsTable($catalog->getName());
}

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

Границы и связанные действия

Проверяйте instanceof Schema перед дальнейшим вызовом, если результат может быть недоступен. Метод не создаёт схему заново и не переносит коллекцию. Проверка существования самой схемы — отдельный existsInDatabase.

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

mysql_xdevapi\Collection::getSessionПозволяет коду, получившему только Collection, обратиться к её Session.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Collection::getSession(): mysql_xdevapi\Session

Позволяет коду, получившему только Collection, обратиться к её Session.

Запись, параметры и результат

public mysql_xdevapi\Collection::getSession(): mysql_xdevapi\Session

Аргументов нет.

Новый PHP-объект Session, связанный с соединением коллекции.

Позволяет коду, получившему только Collection, обратиться к её Session. Официальный пример показывает разные номера PHP-объектов исходного и полученного Session. Разные обёртки не означают независимые серверные транзакции: это нужно понимать до commit, rollback или close.

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

Прочитать черновик общей транзакции

Чтение через этот handle увидит незавершённые изменения того же соединения.

$catalogSession = $catalog->getSession();
$parent = $catalogSession->getSchema($configuredSchemaName);
$sameCatalog = $parent->getCollection($catalog->getName());

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

Оформить безопасное имя для SQL-отчёта

Используем настройки уже связанного сеанса; имя схемы для квалифицированного SQL цитируется отдельно.

$catalogSession = $catalog->getSession();
$quotedName = $catalogSession->quoteName($catalog->getName());

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

Границы и связанные действия

В выбранном PECL 8.0.30 удерживайте Session в переменной до конца работы; временная цепочка getSession()->... может разрушить обёртку и закрыть общее соединение. Для параллельной независимой операции отдельно открывают Session через getSession(uri).

Общая транзакция и время жизни Session связывает объектную модель с наблюдаемым откатом. Отдельные соединения для согласования резервов нужны для независимых участников.

mysql_xdevapi\Schema::existsInDatabaseПроверяет существование схемы, к которой относится текущий объект Schema.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::existsInDatabase(): bool

Проверяет существование схемы, к которой относится текущий объект Schema.

Запись, параметры и результат

public mysql_xdevapi\Schema::existsInDatabase(): bool

Аргументов нет.

true, если схема существует, иначе false.

Проверяет существование схемы, к которой относится текущий объект Schema. Это полезно после Session::getSchema: handle можно получить даже для несуществующего имени. Текст официальной страницы обобщён на schema/table/collection/view, а пример вызывает метод коллекции. Для данного receiver Schema проверяется именно схема; методы других объектов проверяют их собственные цели.

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

Открыть только подготовленную схему

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

$catalogSchema = $session->getSchema($configuredSchemaName);
if (!$catalogSchema->existsInDatabase()) {
    throw new RuntimeException('Проверьте настройку учебной схемы.');
}

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

Отличить опечатку от пустого каталога

Имя store_typo может быть сохранено в PHP-объекте, хотя базы с таким именем нет.

$wrong = $session->getSchema('store_typo');
$name = $wrong->getName();
$exists = $wrong->existsInDatabase();

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

Границы и связанные действия

Не делайте из false вывод, что схема пуста. Не создавайте автоматически базу с именем из HTTP-запроса. Наличие схемы не доказывает наличие коллекции, нужных столбцов или права на конкретный запрос; ошибки выполнения обрабатываются отдельно.

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

mysql_xdevapi\Schema::getCollectionAsTableОткрывает коллекцию через табличный API.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::getCollectionAsTable(string $name): mysql_xdevapi\Table

Открывает коллекцию через табличный API.

Запись, параметры и результат

public mysql_xdevapi\Schema::getCollectionAsTable(string $name): mysql_xdevapi\Table

$name — имя коллекции в данной схеме.

Объект Table для той же коллекции.

Открывает коллекцию через табличный API. Документное и табличное представления ссылаются на одни данные; получения Table недостаточно для создания новой коллекции или копии. Официальный пример получает Collection и Table для people и показывает разные типы объектов. Для табличного чтения JSON доступен через doc и JSON-пути, _id определяет документ. SQL CRUD может обращаться к этому хранилищу, но правила корректных документов сохраняют значение.

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

Получить одну строку исходного документа

В строке есть исходный JSON-документ; это полезно для диагностики конкретной записи.

$table = $schema->getCollectionAsTable($catalogName);
$row = $table->select(['_id', 'doc'])->where('_id = :id')->bind(['id' => 'LED'])->execute()->fetchOne();

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

Выбрать только артикул для отчёта

Сервер выбирает поле и запись; PHP получает уже нужный небольшой результат.

$table = $schema->getCollectionAsTable($catalogName);
$rows = $table->select(["JSON_UNQUOTE(JSON_EXTRACT(doc, '$.sku')) AS sku"])->where('_id = :id')->bind(['id' => 'LED'])->execute()->fetchAll();

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

Границы и связанные действия

Не ожидайте, что JSON-поля sku/stock автоматически станут SQL-столбцами. Выберите нужные пути через выражения; не выгружайте всю коллекцию ради малого отчёта. Прежде чем вручную менять физическую структуру таблицы, учитывайте правила распознавания коллекций и версию сервера; пример структуру не изменяет.

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

mysql_xdevapi\Schema::getCollectionsПолучает список коллекций данной схемы.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::getCollections(): array

Получает список коллекций данной схемы.

Запись, параметры и результат

public mysql_xdevapi\Schema::getCollections(): array

Аргументов нет.

Ассоциативный массив: ключ — имя коллекции, значение — объект Collection.

Получает список коллекций данной схемы. Это уровень объектов базы, а не массив их документов. Пустой список означает отсутствие видимых коллекций, но в схеме могут быть обычные таблицы. Официальный пример показывает ключ people и объект Collection со свойством name. Список помогает выбрать нужный источник или составить служебный экран с дополнительными сведениями.

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

Получить строго выбранный каталог

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

$collections = $schema->getCollections();
$catalog = $collections[$approvedName] ?? null;

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

Сформировать экран только разрешённых каталогов

Читаем количество у каждого разрешённого объекта. Полное содержимое коллекций не загружается.

foreach ($approvedNames as $name) {
    $collection = $collections[$name] ?? null;
    if ($collection instanceof mysql_xdevapi\Collection) {
        $counts[$name] = $collection->count();
    }
}

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

Границы и связанные действия

Не используйте [0] как первую коллекцию: ключи — строки имён. Не рассчитывайте на порядок элементов; для интерфейса задайте явные подписи и порядок. Отсутствие в списке может зависеть от доступности и классификации объекта, а чтение конкретного источника всё равно требует обработки ошибок.

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

mysql_xdevapi\Schema::getNameВозвращает строковое имя базы от объекта Schema.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::getName(): string

Возвращает строковое имя базы от объекта Schema.

Запись, параметры и результат

public mysql_xdevapi\Schema::getName(): string

Аргументов нет.

Имя схемы, связанное с объектом Schema, как строка.

Возвращает строковое имя базы от объекта Schema. Его используют в подписи отчёта, сверке конфигурации и квалифицированном SQL-имени. В официальном примере схема addressbook даёт строку addressbook. Это локальное описание выбранного объекта; для наличия базы нужен existsInDatabase.

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

Сверить с настройкой приложения

Обнаруживаем, что используем другой handle, даже если обе базы существуют.

$name = $catalogSchema->getName();
$configurationMatches = $name === $configuredSchemaName;

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

Собрать квалифицированный SQL-источник

Схема и таблица — два идентификатора; точка остаётся разделителем.

$qualified = $session->quoteName($schema->getName()) . '.' . $session->quoteName($tableName);

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

Границы и связанные действия

Имя не содержит пароль и не является строкой подключения. Не соединяйте его с непроверенным SQL без quoteName. В HTML экранируйте строку; имя схемы вместе с именем коллекции даёт более точную подпись источника, чем имя коллекции отдельно.

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

mysql_xdevapi\Schema::getSessionПолучает Session от уже известной Schema.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::getSession(): mysql_xdevapi\Session

Получает Session от уже известной Schema.

Запись, параметры и результат

public mysql_xdevapi\Schema::getSession(): mysql_xdevapi\Session

Аргументов нет.

Новый PHP-объект Session для соединения данной схемы.

Получает Session от уже известной Schema. Официальный пример показывает исходный и новый объект Session с разными номерами. Это путь вверх по графу объектов: от схемы к соединению, а не создание новой базы или автоматическое открытие независимой серверной сессии.

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

Общее соединение для чтения другой разрешённой схемы

Получаем handle через тот же сеанс; права пользователя не увеличиваются. В лаборатории используем только её подготовленную схему.

$schemaSession = $schema->getSession();
$target = $schemaSession->getSchema($approvedSchemaName);

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

Откатить черновик коллекции этой схемы

Откат виден и исходному Session; постоянные данные до транзакции сохраняются.

$schemaSession = $schema->getSession();
// В текущей транзакции ранее добавлен черновик.
$schemaSession->rollback();

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

Границы и связанные действия

Сохраняйте объект до завершения всех операций, особенно в выбранном PECL 8.0.30. commit/rollback работают с общим соединением. Не запускайте разные независимые транзакции через обёртки, считая их отдельными подключениями.

Общая транзакция и время жизни Session связывает объектную модель с наблюдаемым откатом. Отдельные соединения для согласования резервов нужны для независимых участников.

mysql_xdevapi\Schema::dropCollectionУдаляет коллекцию целиком из схемы.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Schema::dropCollection(string $collection_name): bool

Удаляет коллекцию целиком из схемы.

Запись, параметры и результат

public mysql_xdevapi\Schema::dropCollection(string $collection_name): bool

$collection_name — точное имя коллекции в текущей схеме.

bool результата удаления. В проверенном профиле первое удаление возвращает true, повторное — false с E_WARNING и кодом MySQL 1051.

Удаляет коллекцию целиком из схемы. Официальная страница предупреждает, что описание неполное, содержит строковый аргумент и bool-сигнатуру, а пример сравнивает списки оставшихся таблиц и коллекций. Здесь результат дополнен наблюдаемым поведением PECL 8.0.30: повторное удаление отсутствующего объекта — PHP-предупреждение, а не гарантированное исключение. Это отличие важно для корректного finally.

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

Завершить жизненный цикл своего временного объекта

Точное владение проверено до удаления. Оставшиеся объекты программы очищает finally.

if (!in_array(['type' => 'COLLECTION', 'name' => $temporaryName], $owned, true)) {
    throw new RuntimeException('Объект не принадлежит этой программе.');
}
$removed = $schema->dropCollection($temporaryName);

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

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

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

$handle = $schema->getCollection($temporaryName);
if ($handle->existsInDatabase()) {
    $removed = $schema->dropCollection($temporaryName);
}
$stillExists = $handle->existsInDatabase();

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

Границы и связанные действия

Удаляются документы и структура коллекции. Для отдельных документов нужен remove, для базы целиком — другая операция, не используемая в примере. DDL нельзя обещать вернуть обычным rollback. Не подавляйте все предупреждения: ожидаемое 1051 ловится только вокруг конкретного учебного повторного вызова, прежний handler восстанавливается.

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

mysql_xdevapi\Session::getDefaultSchemaЧитает выбор схемы, обычно заданный в URI подключения.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Session::getDefaultSchema(): ?mysql_xdevapi\Schema

Читает выбор схемы, обычно заданный в URI подключения.

Запись, параметры и результат

public mysql_xdevapi\Session::getDefaultSchema(): ?mysql_xdevapi\Schema

Аргументов нет.

Schema, выбранная для соединения по умолчанию, либо null, если она не задана.

Читает выбор схемы, обычно заданный в URI подключения. Несмотря на подпись «Get default schema name», возвращается объект Schema, а строку имени получают отдельным getName. Это удобно, когда приложение намеренно указывает базу в URI. В нашем учебном профиле URI не содержит пути, поэтому результат null; явно полученный через getSchema объект при этом нормально работает.

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

Проверить наличие настройки перед выводом имени

Отсутствие выбора представлено явно, без Fatal error из вызова метода у null.

$default = $session->getDefaultSchema();
$defaultName = $default instanceof mysql_xdevapi\Schema ? $default->getName() : null;

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

Явно выбрать настроенную схему при отсутствии default

Такой fallback допустим только если обе ветки соответствуют политике приложения. Если база должна быть строго фиксированной, всегда используйте разрешённое имя и сверяйте его.

$default = $session->getDefaultSchema();
$catalogSchema = $default ?? $session->getSchema($configuredSchemaName);

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

Границы и связанные действия

Не вызывайте getName у null. getSchema(name) не следует считать способом изменить default-схему соединения: это получение объекта доступа. Наличие default-объекта само по себе не заменяет проверку существования и обработку запроса.

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

mysql_xdevapi\Session::getSchemaПолучает Schema через существующий Session.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Session::getSchema(string $schema_name): mysql_xdevapi\Schema

Получает Schema через существующий Session.

Запись, параметры и результат

public mysql_xdevapi\Session::getSchema(string $schema_name): mysql_xdevapi\Schema

$schema_name — строка имени схемы/базы, для которой нужен объект доступа.

Новый объект Schema с переданным именем.

Получает Schema через существующий Session. Официальное описание и пример показывают создание PHP-объекта с именем addressbook; это не SQL CREATE DATABASE. Метод удобен для явного выбора подготовленной базы, особенно когда в URI нет схемы по умолчанию. Само получение handle не подтверждает наличие базы.

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

Открыть явно настроенный каталог

Настройка и существование проверяются независимо.

$catalogSchema = $session->getSchema($configuredSchemaName);
$exists = $catalogSchema->existsInDatabase();

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

Вернуться к той же схеме через Session коллекции

Получаем новый путь к тому же объекту, удерживая Session до конца работы.

$catalogSession = $catalog->getSession();
$parent = $catalogSession->getSchema($configuredSchemaName);
$sameCatalog = $parent->getCollection($catalog->getName());

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

Границы и связанные действия

Не принимайте произвольную схему из формы, если пользователь может работать только с одной. Отдельно проверяйте existsInDatabase и обрабатывайте ошибки соединения/прав. getSchema не копирует базу и не мигрирует её структуру.

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

mysql_xdevapi\Session::quoteNameЭкранирует SQL-имя и добавляет необходимые кавычки.

Интерфейсы PECL mysql_xdevapi >= 8.0.11; отдельные страницы методов не указывают начальную версию. Учебное расширение 8.0.30. · mysql_xdevapi

public mysql_xdevapi\Session::quoteName(string $name): string

Экранирует SQL-имя и добавляет необходимые кавычки.

Запись, параметры и результат

public mysql_xdevapi\Session::quoteName(string $name): string

$name — один SQL-идентификатор, который надо оформить: имя схемы, таблицы или столбца.

Строка с корректно оформленным идентификатором по настройкам соединения.

Экранирует SQL-имя и добавляет необходимые кавычки. В проверенном MySQL-профиле это обратные кавычки, а внутренняя обратная кавычка удваивается. Официальный пример специально содержит апострофы, обычные и обратные кавычки внутри имён. Метод предназначен для идентификаторов; для значений он не применяется. Placeholder и bind передают именно значения, не имена SQL-объектов.

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

Разрешённый столбец динамического отчёта

Ключ price отображается в price_cents; неизвестный ключ отвергается до SQL.

$field = chooseReportField('price');
$quotedField = $session->quoteName($field);

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

Имя таблицы и значение фильтра обрабатываются по-разному

Апостроф в значении передаётся через bind, не через ручную замену кавычек.

$qualified = $session->quoteName($schema->getName()) . '.' . $session->quoteName($tableName);
$result = $session->sql('SELECT price_cents FROM ' . $qualified . ' WHERE title = ?')->bind("Maker's lamp")->execute();

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

Границы и связанные действия

Сначала разрешите известные имена, затем оформляйте их. quoteName не скрывает секретные столбцы и не проверяет права бизнес-пользователя. Квалифицированное имя schema.table цитируйте по частям: единый quoteName даст одно имя с точкой внутри. Ключевые слова направления сортировки выбирайте из ASC/DESC отдельно.

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

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

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

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

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

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