Иногда, появляется необходимость выполнить некоторые SQL команды напрямую, без использования Magento 2 моделей и коллекций. В этой небольшой статье я расскажу как выполнять обычные CRUD операции..
Итак, первое что нам понадобится, это создать файл test-direct-sql.php в корне установленной Magento 2.
touch /var/www/m23.sv/public_html/test-direct-sql.php
Теперь добавляем туда подключение файла bootstrap и создаем объект objectManager-а, для загрузки классов
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); ini_set('memory_limit', '128M'); error_reporting(E_ALL); require 'app/bootstrap.php'; $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER); $objectManager = $bootstrap->getObjectManager(); ...
Далее получаем объект \Magento\Framework\App\ResourceConnection и через него объект \Magento\Framework\DB\Adapter\AdapterInterface (в 99% случаев это объект \Magento\Framework\DB\Adapter\Pdo\Mysql)
.. $resource = $objectManager->get('Magento\Framework\App\ResourceConnection'); $connection = $resource->getConnection(); ..
следующим шагом, получаем имя таблицы (core_config_data) с префиксом, если он используется. Именно эту таблицу мы и будем использовать в наших SQL запросах
Теперь, пререходим к выборке данных, делается это так
... $sql = "SELECT * FROM " . $tableName.' WHERE path LIKE "%base_url%"'; $result = $connection->fetchAll($sql) ...
на выходе получим обычный ассоциативный массив
Array ( [0] => Array ( [config_id] => 2 [scope] => default [scope_id] => 0 [path] => web/unsecure/base_url [value] => http://m23.sv:7070/ ) [1] => Array ( [config_id] => 3 [scope] => default [scope_id] => 0 [path] => web/secure/base_url [value] => https://m23.sv:7070/ ) )
Теперь, рассмотрим операцию вставки и обновления данных
try { $sql = "INSERT INTO " . $tableName . " SET scope='default', scope_id=0, path='custom/base_url', value='http://127.0.0.1'"; $connection->query($sql); } catch (Magento\Framework\DB\Adapter\DuplicateException $ex) { $sql = "UPDATE " . $tableName . " SET value='http://127.0.0.1' WHERE path='custom/base_url' AND scope='default' AND scope_id=0"; $connection->query($sql); }
Тут мы делаем INSERT и в случае ошибки "1062 Duplicate entry" делаем обновление записи.
Осталось рассмотреть удаление, делается это так же просто
$sql = "DELETE FROM " . $tableName." WHERE path='custom/base_url' AND scope='default' AND scope_id=0 LIMIT 1"; $connection->query($sql);
Как видите использовать SQL напрямую достаточно просто. Полный код из файла ниже
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); ini_set('memory_limit', '128M'); error_reporting(E_ALL); require 'app/bootstrap.php'; $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER); $objectManager = $bootstrap->getObjectManager(); $resource = $objectManager->get('Magento\Framework\App\ResourceConnection'); $connection = $resource->getConnection(); $tableName = $resource->getTableName('core_config_data'); //gives table name with prefix echo 'Table: '.$tableName.PHP_EOL; // OUTPUT: // Table: core_config_data //Select Data from table $sql = "SELECT * FROM " . $tableName.' WHERE path LIKE "%base_url%"'; $result = $connection->fetchAll($sql); // gives associated array, table fields as key in array. print_r($result); // OUTPUT: // Array // ( // [0] => Array // ( // [config_id] => 2 // [scope] => default // [scope_id] => 0 // [path] => web/unsecure/base_url // [value] => http://m23.sv:7070/ // ) // // [1] => Array // ( // [config_id] => 3 // [scope] => default // [scope_id] => 0 // [path] => web/secure/base_url // [value] => https://m23.sv:7070/ // ) // // ) try { //Insert Data into table $sql = "INSERT INTO " . $tableName . " SET scope='default', scope_id=0, path='custom/base_url', value='http://127.0.0.1'"; $connection->query($sql); } catch (Magento\Framework\DB\Adapter\DuplicateException $ex) { //UPDATE Data into table $sql = "UPDATE " . $tableName . " SET value='http://127.0.0.1' WHERE path='custom/base_url' AND scope='default' AND scope_id=0"; $connection->query($sql); } //Select Data from table $sql = "SELECT * FROM " . $tableName.' WHERE path LIKE "%base_url%"'; $result = $connection->fetchAll($sql); // gives associated array, table fields as key in array. print_r($result); // OUTPUT: // Array // ( // [0] => Array // ( // [config_id] => 2 // [scope] => default // [scope_id] => 0 // [path] => web/unsecure/base_url // [value] => http://m23.sv:7070/ // ) // // [1] => Array // ( // [config_id] => 3 // [scope] => default // [scope_id] => 0 // [path] => web/secure/base_url // [value] => https://m23.sv:7070/ // ) // // [2] => Array // ( // [config_id] => 85 // [scope] => default // [scope_id] => 0 // [path] => custom/base_url // [value] => http://127.0.0.1 // ) // // ) //Delete Data from table $sql = "DELETE FROM " . $tableName." WHERE path='custom/base_url' AND scope='default' AND scope_id=0 LIMIT 1"; $connection->query($sql); //Select Data from table $sql = "SELECT * FROM " . $tableName.' WHERE path LIKE "%base_url%"'; $result = $connection->fetchAll($sql); // gives associated array, table fields as key in array. print_r($result); // OUTPUT: // Array // ( // [0] => Array // ( // [config_id] => 2 // [scope] => default // [scope_id] => 0 // [path] => web/unsecure/base_url // [value] => http://m23.sv:7070/ // ) // // [1] => Array // ( // [config_id] => 3 // [scope] => default // [scope_id] => 0 // [path] => web/secure/base_url // [value] => https://m23.sv:7070/ // ) // // )
--[добавлено]--
Иногда требуется получить существующий connection в каком-нибудь хелпере и в целях отладки не прописывать его в конструктор, сделать это можно вот так
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $resource = $objectManager->get('Magento\Framework\App\ResourceConnection'); $connection = $resource->getConnection(); print_r($connection->fetchAll("SHOW SESSION VARIABLES LIKE 'wait_timeout'"));