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

Дерево руководства
Глава 130 · После первого каталога и транзакций X DevAPI
MySQL X DevAPI: коллекция, схема и Session без путаницы
Открыть нужную схему, найти коллекции, проследить общий Session, прочитать документы через Table и очистить только свои временные объекты.
Открыть нужный источник и понять результат
Нужно открыть правильный каталог, показать оператору его местоположение, получить небольшой отчёт и после демонстрационного импорта удалить только временные данные. Для этого важно различать имя базы, объект доступа, коллекцию документов и соединение. В этой главе каждое звено приводит к наблюдаемому результату: существующей схеме, найденному товару, откатанному черновику или удалённому временному каталогу.
- Session — соединение с MySQL
- Schema — выбранная база php_manual_x139
- Collection — каталог с документом LED
- 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 ещё не подтверждает существование базы. Проверим это отдельно, не создавая базу автоматически и не скрывая опечатку в имени.
- Настройка содержит имя учебной схемы
- getSchema(name) создаёт объект доступа
- existsInDatabase() проверяет наличие на сервере
- 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, затем проверим связь по настоящему откату черновика.
- Collection с товаром LED
- getSchema() → родительская Schema
- getSession() → объект Session для того же соединения
- Черновик 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 |
| Имя коллекции найдено через интерфейс | да |
| Черновик виден через полученный Session | CABLE |
| Черновик после 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 помогает найти объекты коллекций, после чего можно отдельно запросить количество документов. Этот вызов не выгружает содержимое всех каталогов в один массив.
- Schema содержит две коллекции и таблицу журнала
- getCollections() → массив имя → Collection
- Выбираем только два разрешённых имени
- 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 |
| Значения списка являются Collection | mysql_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 для той же коллекции. Проверим, что это второй способ чтения одних данных, а не новая копия каталога.
- Один документ LED со stock=5
- Collection читает JSON-поля
- getCollectionAsTable() открывает ту же коллекцию как Table
- Изменили 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();Результат на исходных данных
| Наблюдение | Результат |
|---|---|
| Исходный документ: SKU | LED |
| Исходный документ: остаток | 5 |
| Table до изменения: остаток | 5 |
| Table после изменения: остаток | 4 |
| Collection после изменения: остаток | 4 |
| Соседний товар: остаток | 2 |
Самостоятельная программа и архив
<?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.
- Выбор price → разрешённое имя price_cents
- quoteName оформляет идентификатор
- Название Maker’s lamp передаётся через bind
- 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-имён: при переименовании колонки меняется одна запись карты, а пользовательский интерфейс сохраняет прежний ключ.
Удалить временную коллекцию и сохранить соседний каталог
После демонстрационного импорта осталась временная коллекция. Нужно убрать её целиком, сохранив рабочий каталог. Выберем точное имя из списка объектов, созданных текущей программой, затем подтвердим удаление и прочитаем соседний товар.
- Две собственные коллекции: импорт и каталог
- В owned записано точное имя завершённого импорта
- dropCollection удаляет только этот объект
- Повторная проверка: импорт отсутствует, 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();Результат на исходных данных
| Наблюдение | Результат |
|---|---|
| Временная коллекция до удаления | есть |
| Результат первого dropCollection | true |
| Временная коллекция после удаления | нет |
| Результат повторного удаления | 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 и запрос под нужный экран помогают получить ровно нужные данные.
Источники и обсуждения
- PHP Manual — DatabaseObject
- PHP Manual — DatabaseObject::existsInDatabase
- PHP Manual — DatabaseObject::getName
- PHP Manual — DatabaseObject::getSession
- PHP Manual — SchemaObject
- PHP Manual — SchemaObject::getSchema
- PHP Manual — Collection::getName
- PHP Manual — Collection::getSchema
- PHP Manual — Collection::getSession
- PHP Manual — Schema::existsInDatabase
- PHP Manual — Schema::getCollectionAsTable
- PHP Manual — Schema::getCollections
- PHP Manual — Schema::getName
- PHP Manual — Schema::getSession
- PHP Manual — Schema::dropCollection
- PHP Manual — Session::getDefaultSchema
- PHP Manual — Session::getSchema
- PHP Manual — Session::quoteName
- MySQL X DevAPI — коллекции как реляционные таблицы
- MySQL X DevAPI — объекты Schema, Collection и Table
- Исходник выбранного PECL mysql_xdevapi 8.0.30
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


