X

Magento 2: выполнения сырого SQL

Иногда, появляется необходимость выполнить некоторые 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'"));

 

Категории: Magento
Тэги: magentosql