Сценарий дампа базы данных PHP – есть ли какие-либо проблемы?

Я нашел функцию PHP для дампа базы данных mySQL, которую кто-то написал, а затем очистил ее и немного отформатировал. Я хотел знать, могу ли я критиковать его. Я запустил его, протестировал его в блоге WordPress, и БД полностью восстановилась, но хотела получить другие глаза на код.

В частности, я ищу отзыв:

  • Все, что может испортить данные – не удалось избежать и т. Д.
  • Нарушение любой передовой практики / принципов
  • Проблемы с безопасностью
  • Все, что вы можете видеть в качестве проблемы

ПРИМЕЧАНИЕ. Я НЕ ищу использовать mysqldump, я хочу полностью сгенерировать эту резервную копию sql из кода. Я также понимаю, что имя файла может генерироваться случайным образом, но файл SQL также будет загружен в dropbox, и я хочу его подстроить под тем же именем.

Благодаря!

Код:

// Variables $dbHost = 'DBHOST'; $dbUser = 'DBUSER'; $dbPassword = 'DBPASSWORD'; $dbName = 'DBNAME'; $tables = '*'; $fileName = 'mydatabase.sql'; // Logic $link = @mysql_connect($dbHost, $dbUser, $dbPassword); $db = @mysql_select_db($dbName, $link); if(!$link || !$db) die("Database Error"); //get all of the tables if($tables == '*') { $tables = array(); $result = mysql_query('SHOW TABLES'); while($row = mysql_fetch_row($result)) { $tables[] = $row[0]; } } else $tables = is_array($tables) ? $tables : explode(',',$tables); // Loop through tables foreach($tables as $table) { $result = mysql_query('SELECT * FROM '. $table); $num_fields = mysql_num_fields($result); $return.= 'DROP TABLE IF EXISTS ' . $table . ';'; $createTable = mysql_fetch_row(mysql_query('SHOW CREATE TABLE ' . $table)); $return .= "\n\n" . $createTable[1] . ";\n\n"; for ($i = 0; $i < $num_fields; $i++) { while($row = mysql_fetch_row($result)) { $return.= 'INSERT INTO ' . $table . ' VALUES('; for($j = 0; $j < $num_fields; $j++) { $row[$j] = addslashes($row[$j]); $row[$j] = ereg_replace("\n","\\n", $row[$j]); if (isset($row[$j])) { $return .= '"' . $row[$j] . '"' ; } else { $return .= '""'; } if ($j < ($num_fields-1)) { $return .= ','; } } $return .= ");\n"; } } $return .="\n\n\n"; } // Save the file $handle = fopen($fileName, 'w+'); fwrite($handle, $return); fclose($handle); 

    Этот сценарий имеет серьезные, деловые проблемы. Он не будет работать ни для одной, ни для тривиальной базы данных.

    • NULL не поддерживаются.
    • Наборы символов не учитываются.
    • Имена таблиц не ограничены.
    • Поддерживаются только таблицы – не просмотры, хранимые процедуры, триггеры, функции и т. Д.
    • addslashes() не является безопасным для персонажа .
    • mysql_query() предварительно выбирает все строки из таблицы, поэтому, если вы запрашиваете таблицу с миллионами строк, вы превысите предел памяти PHP. mysql_unbuffered_query() этого используйте mysql_unbuffered_query() . На второй мысли, я вижу, вы собираете все выходные в $ возврата, так что это спорный вопрос.
    • Ваше подавление ошибок с помощью оператора @ – это плохая практика. Проверяйте ошибки и изящно выходите с информативным сообщением.

    Ваше требование не использовать mysqldump абсурдно.

    Зачем делать так много работы для себя, изобретая колесо, и все еще неправильно? Просто запустите mysqldump через shellexec() .


    Смотрите также:

    • Почему мой сценарий резервного копирования базы данных не работает в php?

    Попробуйте mysql команду mysql или команду mysqldump

    Наборы символов? Возможно, SET NAMES utf8 будет хорошим дополнением.

    Кроме того, что произойдет, если база данных содержит представления?

    В случае, если это очень большая база данных, которую нужно сбрасывать, убедитесь, что ваш сервер (и память выполнения php max для каждого скрипта) имеет достаточно памяти, чтобы сохранить весь возврат $ в памяти, иначе вы лучше покраснете в файл один раз, или каждой линии.

    Это не сбрасывает хранимые процедуры, функции, представления, триггеры и т. Д.

    Изменить: вы также можете сбрасывать процедуры и т. Д. Просто используйте, т. SHOW PROCEDURE STATUS; для получения списка процедур, а затем SHOW CREATE PROCEDURE для каждой процедуры. То же самое для функций, представлений, триггеров …

    Не забывайте, SHOW CREATE DATABASE; или.

    создать резервную БД:

     <?php $dbHost = 'DBHOST'; $dbUser = 'DBUSER'; $dbPassword = 'DBPASSWORD'; $dbName = 'DBNAME'; $tables = '*'; backup_tables($dbHost,$dbUser,$dbPassword,$tables); /* backup the db OR just a table */ function backup_tables($host,$user,$pass,$name,$tables = '*') { $db = new PDO("mysql:host=$host;dbname=$name;", $user, $pass); //get all of the tables if($tables == '*') { $tables = array(); $result = $db->query('SHOW TABLES'); $tables= $result->fetchAll(PDO::FETCH_COLUMN, 0); } else { $tables = is_array($tables) ? $tables : explode(',',$tables); } $return=""; //cycle through foreach($tables as $table) { $return.= 'DROP TABLE IF EXISTS '.$table.';'; $result=$db->query('SHOW CREATE TABLE '.$table); $row2 = $result->fetch(PDO::FETCH_NUM); $return.= "\n\n".$row2[1].";\n\n"; $result = $db->query('SELECT * FROM '.$table); foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $key=>$value) { // build query... $return .= "INSERT INTO $table (`".implode("`, `", array_keys($value))."`) VALUES ('".implode("', '", $value)."');\n\n"; } $return.="\n\n\n"; } //save file $handle = fopen('db-backup-'.date('Ymd--Hi-s').'-'.(md5(implode(',',$tables))).'.sql','w+'); fwrite($handle,$return); fclose($handle); }