Как сделать, чтобы Sypex Dumper работал с MySQLi InnoDB на PHP 8

Sypex Dumper 2.0.11 от 28 августа 2013 слегка устарел и не работает под PHP 7.4, из-за того, что седьмой Похапе не поддерживает MySQL, а SXD поддерживает только это расширение. Исправить это не просто, а очень просто.

Кому лень всё это читать, разбираться и менять — в конце статьи есть ссылка на исправленный файл.

Файл index.php

Открываем наш SXD в браузере. Начиная с PHP 7.3 появляется ошибка:

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in index.php

Дело в том, что в ранних версиях PHP оператор continue применялся в конструкциях switch и действал подобно оператору break. Теперь, если конструкция switch находится внутри цикла, интерпретатор ругается на это, поэтому в этих случаях continue необходимо заменить на break. Это нужно сделать в следующих циклах:

foreach($temp as $a)
foreach($list as $item)
while($item = mysql_fetch_assoc($r))

В файле index.php закомментировать вывод ошибок. Возможно понадобится включить отображение ошибок на хостинге.

//error_reporting(0);

Появится следующая ошибка:

Notice: Undefined property: Sypex_Dumper::$try in index.php

Необходимо произвести следующие замены:

if(!empty($SXD->try)) return; //if($SXD->try) return;

Далее, необходимо авторизоваться. Появятся следующие ошибки:

Fatal error: Uncaught Error: Call to undefined function mysql_connect() in index.php:185 Stack trace: #0 index.php(167): Sypex_Dumper->connect() #1 index.php(22): Sypex_Dumper->init(false) #2 {main} thrown in index.php

Необходимо заменить все вхождения mysql_ на mysqli_ и, где это необходимо, добавить идентификатор соединения.  В функции подключения к БД удалён фрагмент, присоединяющий к хосту номер порта, т.к. на некоторых хостингах подобный формат записи не работает. При необходимости, его можно добавить 5-м параметром.

$this->mysqli = mysqli_connect($this->CFG['my_host'], $this->CFG['my_user'], $this->CFG['my_pass']) //mysql_connect($this->CFG['my_host'] . ($this->CFG['my_host']{0} != ':' ? ":{$this->CFG['my_port']}" : ''),  $this->CFG['my_user'], $this->CFG['my_pass'])

mysqli_set_charset($this->mysqli, $charset) //mysql_set_charset($charset)

mysqli_get_server_info($this->mysqli) //mysql_get_server_info()

Запросы к БД и небуферизованные запросы:

mysqli_query($this->mysqli, $query); //mysql_query($query);

mysqli_query($this->mysqli, $query, MYSQLI_USE_RESULT); //mysql_unbuffered_query($query)

В функциях, связанных с обработкой результата, идентификатор соединения дописывать не нужно.

mysqli_num_rows($result) //mysql_num_rows($result)

mysqli_fetch_assoc($result) //mysql_fetch_assoc($result)

mysqli_fetch_row($result) //mysql_fetch_row($result)

mysqli_fetch_array($result) //mysql_fetch_array($result)

mysqli_free_result($result) //mysql_free_result($result)

Другие операции с БД:

mysqli_error($this->mysqli) //mysql_error()

mysqli_select_db($this->mysqli, $dbname); //mysql_select_db($dbname);

mysqli_affected_rows($this->mysqli) //mysql_affected_rows()

mysqli_real_escape_string($this->mysqli, $string) //mysql_real_escape_string($string)

Кроме того, в PHP 7 возникает следующая ошибка.

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Sypex_Dumper has a deprecated constructor in index.php

Следует произвести следующую замену:

function __construct() { //function Sypex_Dumper() {

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

while($q = sxd_read_sql($this->fh_tmp, $seek, $ei)){
  usleep(...);

Если вы используете подсистему хранения данных InnoDB вместо MyISAM, то можете столкнуться с тем, что не все таблицы будут экспортированы из-за того, что в InnoDB не хранится точное количество записей в таблице. И если там 0, а по факту больше нуля, то записи просто не эскпортируются. Чтобы этого избежать, необходимо внутри цикла while($item = mysqli_fetch_assoc($r)), который, в свою очередь, находится внутри foreach($queries AS $query), сразу же после $n = $item[$query[1]]; добавить следующие строчки:

if($t == 'TA')
{
  $r2 = mysqli_query($this->mysqli, 'select count(*) from `'.$n.'`') or sxd_my_error();
  $i2 = mysqli_fetch_row($r2);
  $item['Rows'] = $i2[0];
}

Таким образом, количество записей прочитается принудительно, запросом.

Если экспортировать только структуру, то возникает ошибка несоответствия типов (?). Чтобы её исправить, следует произвести следующую замену:

$item['Rows'] = $item['Data_length'] = 0; //$item['Rows'] = $item['Data_length'] = '';

Если импортировать только процедуры, функции и триггеры без таблиц, то выполнение прерывается из-за ошибок, поэтому перед foreach($this->JOB['todo']['TA'] AS $tab) нужно добавить:

if(!empty($this->JOB['todo']['TA']))

Начиная с версии PHP 8 появляется ошибка:

Fatal error: Array and string offset access syntax with curly braces is no longer supported

Чтобы её исправить, необходимо заменить у переменных фигурные скобки на квадратные в следующих строках:

switch($q{0}){ // в двух местах
case '-' && $q{1} == '-':
if($pos > 0 && $l{$pos-1} === ',') {

После этого появляется следующая ошибка:

Fatal error: Uncaught Error: Call to undefined function get_magic_quotes_gpc(): Sypex_Dumper->init(false)

Чтобы её исправить, необходимо закомментировать условие:

if (get_magic_quotes_gpc()) {
  $_POST = sxd_antimagic($_POST);
}

Скачать исправленный файл index.php для PHP 7.4 от 1 апреля 2020
Скачать исправленный файл index.php для PHP 8.0 от 16 марта 2021

Файл info.js

Чтобы увеличить интервал запросов к info.php, нужно в файле sxd.js поменять значение 33 например на 3333.

setInterval(oncomplete,33)

Читайте так же статью о том как установит IMagick на XAMPP.

Комментарии

Низкий поклон! Спасибо!

Благодарю за науку

Работает спасиб большое!

С произвольным портом, отличным от 3306, не работает.
В версии php-7.4.14 возникают ошибки, с 7.3 - работает

1

Здравствуйте!

У вас есть вопрос или вам нужна помощь?

Спасибо, ваш вопрос принят.

Ответ на него появится на сайте в ближайшее время.