Автор Тема: Доступ из prestashop к другой базе данных, расположенной на другом сервере  (Прочитано 343 раз)

07 Октябрь 2021, 12:15:13
  • Ветеран
  • *****
  • Сообщений: 527
  • Репутация: +1/-0
  • Сообщество PrestaShop
    • Просмотр профиля
День добрый!

Возникла необходимость обратиться из prestashop помимо локальной БД ещё и к другой базе данных, расположенной на другом сервере.
Что необходимо переопределить/изменить, чтобы использовать класс ядра DB Prestashop?

Т.е. при обращении к БД на другом сервере я хочу использовать такой код.
$sql = 'SELECT * FROM `'._DB_PREFIX_.'shop`';
if ($results = Db::getInstance()->ExecuteS($sql))
foreach ($results as $row)
echo $row['id_shop'].' - '.$row['name'];

Заранее большой спасибо!
08 Октябрь 2021, 11:35:43
Ответ #1
  • Ветеран
  • *****
  • Сообщений: 22125
  • Репутация: +25303/-1
  • Prestashop - просто и эффективно
    • Просмотр профиля
Если базы одинаковые, тогда менять только url базы с localhost на удаленный.
Эксперт Prestashop - решения всех проблем, написание модулей, создание тем для интернет-магазинов под Prestashop.
Эксперт Magento - создам сайт на Magento, программирование кастомных модулей для Magento, кастомизация тем Magento.
Лучшие цены!!!
08 Октябрь 2021, 12:57:36
Ответ #2
  • Ветеран
  • *****
  • Сообщений: 527
  • Репутация: +1/-0
  • Сообщество PrestaShop
    • Просмотр профиля
Если базы одинаковые, тогда менять только url базы с localhost на удаленный.

Думаю, что нашёл ответ на свой вопрос.

В классе DB имеем:

public static function getInstance($master = true)
    {
        static $id = 0;

        // This MUST not be declared with the class members because some defines (like _DB_SERVER_) may not exist yet (the constructor can be called directly with params)
        if (!self::$_servers) {
            self::$_servers = array(
                array('server' => _DB_SERVER_, 'user' => _DB_USER_, 'password' => _DB_PASSWD_, 'database' => _DB_NAME_), /* MySQL Master server */
            );
        }

        if (!$master) {
            Db::loadSlaveServers();
        }

Насколько я вижу, можно изменить настройку с
$master = true на $master = false,
тогда параметры подключения к БД будут браться из метода:
Db::loadSlaveServers();
т.е. как то так:

protected static function loadSlaveServers()
    {
        if (self::$_slave_servers_loaded !== null) {
            return;
        }

        // Add here your slave(s) server(s) in this file
        if (file_exists(_PS_ROOT_DIR_.'/config/db_slave_server.inc.php')) {
            self::$_servers = array_merge(self::$_servers, require(_PS_ROOT_DIR_.'/config/db_slave_server.inc.php'));
        }

        self::$_slave_servers_loaded = true;
    }

А настройки подключения к удалённой БД прописать здесь:
/config/db_slave_server.inc.php
и далее используем вот так:
$results = Db::getInstance(false)->ExecuteS($sql)
Что скажете?
02 Ноябрь 2021, 10:27:24
Ответ #3
  • Старожил
  • ****
  • Сообщений: 259
  • Репутация: +2/-0
  • Сообщество PrestaShop
    • Просмотр профиля
Что скажете?

Я для себя решил этот вопрос так
1. Модифицировал DB::getInstance
    public static function getInstance($master = 0)
    {
        static $id = 0;

        // This MUST not be declared with the class members because some defines (like _DB_SERVER_) may not exist yet (the constructor can be called directly with params)
        if (!self::$_servers) {
            self::$_servers = array(
                array('server' => _DB_SERVER_, 'user' => _DB_USER_, 'password' => _DB_PASSWD_, 'database' => _DB_NAME_), /* MySQL Master server */
            );
        }


        if ((int)$master > 0) {
            Db::loadSlaveServers();
        }

        $total_servers = count(self::$_servers);
        if ((int)$master == 0 || $total_servers == 1) {
            $id_server = 0;
        } else {
            $id++;
//            $id_server = ($total_servers > 2 && ($id % $total_servers) != 0) ? $id % $total_servers : 1;
            $id_server = (int)$master;  
        }

        if (!isset(self::$instance[$id_server])) {
            $class = Db::getClass();
            self::$instance[$id_server] = new $class(
                self::$_servers[$id_server]['server'],
                self::$_servers[$id_server]['user'],
                self::$_servers[$id_server]['password'],
                self::$_servers[$id_server]['database']
            );
        }

        return self::$instance[$id_server];
    }
2. В файле db_slave_server.inc.php записываю любое количество серверов (локальных или удаленных)
return array(
    array('server' => 'localhost', 'user' => '***', 'password' => '***', 'database' => '***1'),
    array('server' => 'localhost', 'user' => '***', 'password' => '***', 'database' => '***2'),
);
return array();
3. Обращаюсь к нужной мне БД:
$results = Db::getInstance()->ExecuteS($sql) - родная БД
$results = Db::getInstance(1)->ExecuteS($sql) - ***1 БД
$results = Db::getInstance(2)->ExecuteS($sql) - ***2 БД