这个函数在这里 http://davidwalsh.name/backup-mysql-database-php
已经在互联网上流传了一段时间并且非常有名,但它使用的是旧的 MySQL API。有没有人有相同的但在 PDO 中?如果没有,有人想做一个吗?
是否有可能,我在某处读到 PDO 不执行 SHOW CREATE TABLE - 对吗?
这个函数在这里 http://davidwalsh.name/backup-mysql-database-php
已经在互联网上流传了一段时间并且非常有名,但它使用的是旧的 MySQL API。有没有人有相同的但在 PDO 中?如果没有,有人想做一个吗?
是否有可能,我在某处读到 PDO 不执行 SHOW CREATE TABLE - 对吗?
那个备份脚本很荒谬,没有人应该制作另一个版本。我以前看过那个脚本,也有类似的尝试,但他们有很多问题:
另请参阅我过去对不幸的 David Walsh 备份脚本的回答:
回复您的评论:
阅读您链接到的页面上的评论。很多人已经发现了问题,有些人已经修复或至少提出了建议。
我认为这个脚本将所有内容附加到一个字符串中的事实是一个交易破坏者,但更改脚本以首先打开输出文件,然后在循环期间输出每一行的数据,然后关闭文件应该不难循环之后。这很简单,我不确定为什么脚本不这样做。但很明显,该脚本没有经过很好的测试。
但无论如何,我不会试图重新发明这个轮子。Mysqldump 或 mydumper 可以很好地完成这项工作。FWIW,您不必在数据库所在的同一台服务器上运行 mysqldump 。Mysqldump 支持一个选项,--host
因此您可以在任何地方运行 mysqldump 来备份远程数据库,只要防火墙不阻止您的客户端连接。基本上,如果您可以从某个客户端主机将 PHP 应用程序连接到数据库,则可以连接 mysqldump。
如果这真的不是一个选项,那么我会使用 phpmyadmin 的数据库转储功能。这些都是成熟且经过充分测试的,它们可以正确地转储所有内容。这是一篇描述如何使用转储功能的文章:
http://www.techrepublic.com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/
[从您的回答中复制我的评论:]
这是进入代码审查,这不是 StackOverflow 的目的。但简而言之:
但它正在到达那里,不是吗?
是的,这比原来的大卫沃尔什剧本要好。:-)
NULL 到 '' 有什么问题?
NULL 与 SQL 中的 '' 不同(Oracle 除外,但在这种情况下它们不符合 SQL 标准)。查看MySQL,最好插入 NULL 或空字符串?
表结构必须非常大才能最大内存。每个插入行都单独写入文件,因此,对于最大内存,行必须非常大。
我误读了有关内存限制问题的代码。您正在为每一行编写输出,所以没关系(除非该行包含 1GB 的 blob 或其他东西)。
但是您不应该只输出带有逗号分隔的行集的单个 INSERT 语句。甚至mysqldump --extended-insert
输出有限长度的数据,然后开始一个新的 INSERT 语句。标准是 INSERT 语句的长度是否适合 的选项参数--net-buffer-length
。
“”字符串分隔符有什么问题?我如何获得 ANSI 的?
在 ANSI SQL 中,单引号 '' 用于分隔字符串文字或日期文字。双引号“”用于分隔标识符,如表名或列名。默认情况下,MySQL 将它们视为相同,但这是非标准的。请参阅不同的数据库是否使用不同的名称引用?. 如果您尝试在您拥有的 MySQL 服务器上导入备份数据SET SQL_MODE=ANSI_QUOTES
,则导入将失败。
哪些表格没有分隔?
示例:query('SELECT * FROM '.$table);
实际上,您在查询中使用 $table 的其他每种情况。在脚本输出的 INSERT 语句中,您只对表进行了一次分隔。
所有的 $tables 都没有分隔,它们都需要用“”吗?
MySQL 总是将反引号识别为标识符分隔符,并将单引号识别为字符串/日期。但是双引号会根据我提到的 SQL_MODE 改变含义。您不能假设哪个 SQL_MODE 对您还原的 MySQL 实例有效,因此最好使用反引号作为标识符,使用单引号作为字符串。您在查询表时对它们进行分隔的原因是您的表名可能是 SQL 保留字或包含特殊字符等。
你可以在mysql中插入不带分隔符的浮点数,还是需要''?谢谢
您可以插入所有没有分隔符的数字类型。只有字符串和日期需要分隔符。见 dev.mysql.com/doc/refman/5.6/en/literals.html
对于任何寻找类似于 mysqldump 的功能的人,这里是最新的草案,上面/下面的评论中讨论的缺陷已经解决。
require 'login.php';
$DBH = new PDO("mysql:host=$db_hostname;dbname=$db_database; charset=utf8", $db_username, $db_password);
//put table names you want backed up in this array.
//leave empty to do all
$tables = array();
backup_tables($DBH, $tables);
function backup_tables($DBH, $tables) {
$DBH->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
//Script Variables
$compression = false;
$BACKUP_PATH = "";
$nowtimename = time();
//create/open files
if ($compression) {
$zp = gzopen($BACKUP_PATH . $nowtimename . '.sql.gz', "a9");
} else {
$handle = fopen($BACKUP_PATH . $nowtimename . '.sql', 'a+');
}
//array of all database field types which just take numbers
$numtypes = array('tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'float', 'double', 'decimal', 'real');
//get all of the tables
if (empty($tables)) {
$pstm1 = $DBH->query('SHOW TABLES');
while ($row = $pstm1->fetch(PDO::FETCH_NUM)) {
$tables[] = $row[0];
}
} else {
$tables = is_array($tables) ? $tables : explode(',', $tables);
}
//cycle through the table(s)
foreach ($tables as $table) {
$result = $DBH->query("SELECT * FROM $table");
$num_fields = $result->columnCount();
$num_rows = $result->rowCount();
$return = "";
//uncomment below if you want 'DROP TABLE IF EXISTS' displayed
//$return.= 'DROP TABLE IF EXISTS `'.$table.'`;';
//table structure
$pstm2 = $DBH->query("SHOW CREATE TABLE $table");
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);
$return .= "\n\n" . $ifnotexists . ";\n\n";
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle, $return);
}
$return = "";
//insert values
if ($num_rows) {
$return = 'INSERT INTO `' . $table . '` (';
$pstm3 = $DBH->query("SHOW COLUMNS FROM $table");
$count = 0;
$type = array();
while ($rows = $pstm3->fetch(PDO::FETCH_NUM)) {
if (stripos($rows[1], '(')) {
$type[$table][] = stristr($rows[1], '(', true);
} else {
$type[$table][] = $rows[1];
}
$return .= "`" . $rows[0] . "`";
$count++;
if ($count < ($pstm3->rowCount())) {
$return .= ", ";
}
}
$return .= ")" . ' VALUES';
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle, $return);
}
$return = "";
}
$count = 0;
while ($row = $result->fetch(PDO::FETCH_NUM)) {
$return = "\n\t(";
for ($j = 0; $j < $num_fields; $j++) {
//$row[$j] = preg_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) {
//if number, take away "". else leave as string
if ((in_array($type[$table][$j], $numtypes)) && (!empty($row[$j]))) {
$return .= $row[$j];
} else {
$return .= $DBH->quote($row[$j]);
}
} else {
$return .= 'NULL';
}
if ($j < ($num_fields - 1)) {
$return .= ',';
}
}
$count++;
if ($count < ($result->rowCount())) {
$return .= "),";
} else {
$return .= ");";
}
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle, $return);
}
$return = "";
}
$return = "\n\n-- ------------------------------------------------ \n\n";
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle, $return);
}
$return = "";
}
$error1 = $pstm2->errorInfo();
$error2 = $pstm3->errorInfo();
$error3 = $result->errorInfo();
echo $error1[2];
echo $error2[2];
echo $error3[2];
if ($compression) {
gzclose($zp);
} else {
fclose($handle);
}
}
根据https://stackoverflow.com/a/18281687/2259391mysqldump
的建议,使用exec
. 归结为:
<?php
function importDatabase($host, $user, $password, $database, $backupFilePath)
{
//returns true iff successfull
return exec('mysqlimport --host '. $host .' --user '. $user .' --password '. $password .' '. $database .' '.targetFilePath) === 0;
}
function exportDatabase($host, $user, $password, $database, $targetFilePath)
{
//returns true iff successfull
return exec('mysqldump --host '. $host .' --user '. $user .' --password '. $password .' '. $database .' --result-file='.targetFilePath) === 0;
}
All PDO
and ext/mysql
do 都是将命令包装到底层数据库(在本例中为 MySQL)。也就是说,没有什么可以停止PDO
运行SHOW CREATE TABLE
或其他命令。
出于所有意图和目的,您几乎可以替换:
- $link = mysql_connect($host,$user,$pass);
- mysql_select_db($name,$link);
+ $link = new PDO("mysql:host=$host;dbname=$name", $user, $pass);
而不是
$result = mysql_query($query);
mysql_fetch_assoc($result);
利用
$result = $link->query($query);
$result->fetch();
我刚刚完成了大卫沃尔什原始备份功能的PDO版本。
我还对其进行了改进以解决Bill Karwin 的回答中提到的问题;处理 NULL,写入单独的行,因此没有内存问题,带有反引号等。
给出了 mysqldump 所做的几乎完全一样的事情。
可以做一点整理,但在这里,请就任何改进提出建议
require 'login.php';
$DBH = new PDO("mysql:host=$db_hostname;dbname=$db_database; charset=utf8", $db_username, $db_password);
//put table names you want backed up in this array.
//leave empty to do all
$tables = array();
backup_tables($DBH, $tables);
function backup_tables($DBH, $tables) {
$DBH->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING );
//Script Variables
$compression = false;
$BACKUP_PATH = "";
$nowtimename = time();
//create/open files
if ($compression) {
$zp = gzopen($BACKUP_PATH.$nowtimename.'.sql.gz', "w9");
} else {
$handle = fopen($BACKUP_PATH.$nowtimename.'.sql','a+');
}
//array of all database field types which just take numbers
$numtypes=array('tinyint','smallint','mediumint','int','bigint','float','double','decimal','real');
//get all of the tables
if(empty($tables)) {
$pstm1 = $DBH->query('SHOW TABLES');
while ($row = $pstm1->fetch(PDO::FETCH_NUM)) {
$tables[] = $row[0];
}
} else {
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through the table(s)
foreach($tables as $table) {
$result = $DBH->query('SELECT * FROM '.$table);
$num_fields = $result->columnCount();
$num_rows = $result->rowCount();
$return="";
//uncomment below if you want 'DROP TABLE IF EXISTS' displayed
//$return.= 'DROP TABLE IF EXISTS `'.$table.'`;';
//table structure
$pstm2 = $DBH->query('SHOW CREATE TABLE '.$table);
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);
$return.= "\n\n".$ifnotexists.";\n\n";
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle,$return);
}
$return = "";
//insert values
if ($num_rows){
$return= 'INSERT INTO `'.$table."` (";
$pstm3 = $DBH->query('SHOW COLUMNS FROM '.$table);
$count = 0;
$type = array();
while ($rows = $pstm3->fetch(PDO::FETCH_NUM)) {
if (stripos($rows[1], '(')) {$type[$table][] = stristr($rows[1], '(', true);
} else $type[$table][] = $rows[1];
$return.= $rows[0];
$count++;
if ($count < ($pstm3->rowCount())) {
$return.= ", ";
}
}
$return.= ")".' VALUES';
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle,$return);
}
$return = "";
}
while($row = $result->fetch(PDO::FETCH_NUM)) {
$return= "\n\t(";
for($j=0; $j<$num_fields; $j++) {
$row[$j] = addslashes($row[$j]);
//$row[$j] = preg_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) {
//if number, take away "". else leave as string
if (in_array($type[$table][$j], $numtypes)) $return.= $row[$j] ; else $return.= '"'.$row[$j].'"' ;
} else {
$return.= '""';
}
if ($j<($num_fields-1)) {
$return.= ',';
}
}
$count++;
if ($count < ($result->rowCount())) {
$return.= "),";
} else {
$return.= ");";
}
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle,$return);
}
$return = "";
}
$return="\n\n-- ------------------------------------------------ \n\n";
if ($compression) {
gzwrite($zp, $return);
} else {
fwrite($handle,$return);
}
$return = "";
}
$error1= $pstm2->errorInfo();
$error2= $pstm3->errorInfo();
$error3= $result->errorInfo();
echo $error1[2];
echo $error2[2];
echo $error3[2];
if ($compression) {
gzclose($zp);
} else {
fclose($handle);
}
}
function backupDB()
{
$db_config = getDbConfigFromWordPress();
if ($db_config === false) {
unset($db_config);
logMessage('Unable to get database configuration from WordPress', true, 'red');
return false;
}
$new_backup_file = __DIR__ . DIRECTORY_SEPARATOR . 'newbackup_xxx_date.sql';
if (is_file($new_backup_file) && is_writable($new_backup_file)) {
@unlink($new_backup_file);
} elseif (is_file($new_backup_file) && !is_writable($new_backup_file)) {
logMessage('Unable to remove new backup SQL file. This is necessary to create backup SQL file.', true, 'red');
return false;
}
unset($new_backup_file);
$dbh = new \PDO('mysql:dbname=' . $db_config['dbname'] . ';host=' . $db_config['dbhost'] . ';charset=' . $db_config['dbcharset'], $db_config['dbuser'], $db_config['dbpassword']);
$dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
$dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
$sth = $dbh->prepare('SHOW TABLES');
$sth->execute();
$result = $sth->fetchAll(\PDO::FETCH_COLUMN);
$tables = [];
if (is_array($result) && !empty($result)) {
foreach ($result as $row) {
if (is_string($row) && stristr($row, $db_config['tableprefix']) !== false) {
$tables[] = $row;
} elseif (is_array($row) && array_key_exists(0, $row) && stristr($row[0], $db_config['tableprefix']) !== false) {
$tables[] = $row[0];
}
}// endforeach;
natcasesort($tables);
}
$sth->closeCursor();
unset($result, $row, $sth);
// begins export string header.
$export_sql = '-- Manual backup SQL Dump'."\n\n";
$export_sql .= 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";'."\n\n\n";
$export_sql .= '--'."\n";
$export_sql .= '-- Database: `' . $db_config['dbname'] . '`'."\n";
$export_sql .= '--'."\n\n";
unset($db_config);
writeDownBackupDB($export_sql);
unset($export_sql);
// starting to loop thru tables.
if (isset($tables) && is_array($tables)) {
foreach ($tables as $table) {
$export_sql = '-- --------------------------------------------------------'."\n\n";
$export_sql .= '--'."\n";
$export_sql .= '-- Table structure for table `' . $table . '`'."\n";
$export_sql .= '--'."\n\n";
$export_sql .= 'DROP TABLE IF EXISTS `' . $table . '`;'."\n";
$sth = $dbh->prepare('SHOW CREATE TABLE `' . $table . '`');
$sth->execute();
$row = $sth->fetch(\PDO::FETCH_NUM);
if (isset($row[1])) {
$create_sql_string = $row[1];
$create_sql_string = str_replace(['CREATE TABLE `'], ['CREATE TABLE IF NOT EXISTS `'], $create_sql_string);
if (substr($create_sql_string, -1) != ';') {
$create_sql_string .= ' ;';
}
} else {
$create_sql_string = '';
}
unset($row);
$export_sql .= $create_sql_string."\n\n";
$sth->closeCursor();
unset($sth);
writeDownBackupDB($export_sql);
unset($export_sql);
$export_sql = '--'."\n";
$export_sql .= '-- Dumping data for table `' . $table . '`'."\n";
$export_sql .= '--'."\n\n";
writeDownBackupDB($export_sql);
unset($export_sql);
// get fields
$sth = $dbh->prepare('SELECT * FROM `' . $table . '` LIMIT 1');
$sth->execute();
$result = $sth->fetch(\PDO::FETCH_ASSOC);
if (is_array($result)) {
$fields = array_keys($result);
} else {
$fields = [];
}
$sth->closeCursor();
unset($result, $sth);
// get fields type
$sth = $dbh->prepare('DESCRIBE `' . $table . '`');
$sth->execute();
$table_columns = $sth->fetchAll();
$columns = [];
if (is_array($table_columns)) {
foreach ($table_columns as $column) {
$columns[$column->Field] = [
'field' => $column->Field,
'type' => $column->Type,
'null' => $column->Null,
'default' => $column->Default,
];
}// endforeach;
unset($column);
}
$sth->closeCursor();
unset($sth, $table_columns);
if (isset($fields) && is_array($fields) && !empty($fields)) {
$select_string = 'SELECT ';
$i_count_field = 1;
foreach ($fields as $field) {
$select_string .= 'IF (`' . $field . '` IS NULL, \'FIELD_VALUE_NULL\', `' . $field . '`) AS `' . $field . '`';
if ($i_count_field < count($fields)) {
$select_string .= ', ';
}
$i_count_field++;
}// endforeach;
unset($i_count_field, $field);
$select_string .= ' FROM `' . $table . '`';
$sth = $dbh->prepare($select_string);
unset($select_string);
$sth->execute();
$result = $sth->fetchAll();
$export_sql = '';
if (is_array($result) && !empty($result)) {
// generate INSERT INTO `table_name` string.
$export_sql .= 'INSERT INTO `' . $table . '` (';
$i_count = 1;
foreach ($fields as $field) {
$export_sql .= '`' . $field . '`';
if ($i_count < count($fields)) {
$export_sql .= ', ';
}
$i_count++;
}// endforeach;
unset($field, $i_count);
$export_sql .= ') VALUES'."\n";
writeDownBackupDB($export_sql);
unset($export_sql);
// generate VALUES of INSERT INTO.
if (is_array($result)) {
$i_count = 1;
$i_count_break = 1;
foreach ($result as $row) {
$export_sql = '(';
$i_count_fields = 1;
foreach ($fields as $field) {
$field_value = $row->{$field};
// escape slash
$field_value = str_replace('\\', '\\\\', $field_value);
// sanitize new line
$field_value = str_replace(["\r\n", "\r", "\n"], ['\r\n', '\r', '\n'], $field_value);
// escape single quote
$field_value = str_replace('\'', '\'\'', $field_value);
// change value to NULL if it is NULL.
if ($field_value === 'FIELD_VALUE_NULL') {
$field_value = 'NULL';
}
// detect field value type and cloak with single quote.
if (isset($columns[$field]['type']) &&
(
stristr($columns[$field]['type'], 'tinyint(') !== false ||
stristr($columns[$field]['type'], 'smallint(') !== false ||
stristr($columns[$field]['type'], 'mediumint(') !== false ||
stristr($columns[$field]['type'], 'int(') !== false ||
stristr($columns[$field]['type'], 'bigint(') !== false
)
) {
// this field column type is int
if (!is_numeric($field_value) && $field_value !== 'NULL') {
$field_value = '\'' . $field_value . '\'';
}
} else {
if ($field_value !== 'NULL') {
$field_value = '\'' . $field_value . '\'';
}
}
$export_sql .= $field_value;
unset($field_value);
if ($i_count_fields < count($fields)) {
$export_sql .= ', ';
}
$i_count_fields++;
}// endforeach;
unset($field, $i_count_fields);
$export_sql .= ')';
if ($i_count < count($result)) {
if ($i_count_break >= 30) {
$export_sql .= ';'."\n";
writeDownBackupDB($export_sql);
unset($export_sql);
$i_count_break = 0;
$export_sql = 'INSERT INTO `' . $table . '` (';
$i_count_fields = 1;
foreach ($fields as $field) {
$export_sql .= '`' . $field . '`';
if ($i_count_fields < count($fields)) {
$export_sql .= ', ';
}
$i_count_fields++;
}// endforeach;
unset($field, $i_count_fields);
$export_sql .= ') VALUES'."\n";
writeDownBackupDB($export_sql);
unset($export_sql);
$export_sql = '';
} else {
$export_sql .= ','."\n";
}
} else {
$export_sql .= ';'."\n\n";
}
$i_count++;
$i_count_break++;
writeDownBackupDB($export_sql);
unset($export_sql);
}// endforeach;
unset($i_count, $i_count_break, $result, $row);
}
} else {
$export_sql .= "\n";
writeDownBackupDB($export_sql);
unset($export_sql);
}
unset($fields);
$sth->closeCursor();
unset($result, $sth);
} else {
$export_sql = "\n";
writeDownBackupDB($export_sql);
unset($export_sql);
}
unset($export_sql);
}// endforeach;
unset($table);
}
unset($tables);
unset($dbh);
logMessage('Backup DB completed. Max memory usage is ' . formatBytes(memory_get_peak_usage(true)) . '.', true, 'green');
return true;
}// backupDB
/**
* Write content to backup SQL file by append.
*
* @param string $content
*/
function writeDownBackupDB($content)
{
$new_backup_file = __DIR__ . DIRECTORY_SEPARATOR . 'newbackup_xxx_date.sql';
$handle = fopen($new_backup_file, 'a+');
fwrite($handle, $content);
fclose($handle);
unset($handle, $new_backup_file);
}// writeDownBackupDB
logMessage('Beginning backup DB.', true, 'light_gray');
backupDB();
请注意...
logMessage()
, getDbConfigFromWordPress()
。请在使用前删除。$db_config['tableprefix']
或$db_config[...]
必须改变的东西。我通过一些修改实现了 Lan 的最新版本(见下面的代码):
添加 csv 选项的一个原因是,当它是多字节(亚洲脚本)时,我发现无法从 TEXT(UTF8)格式的 sql 文件中导入数据。它确实适用于 BLOB 格式,但是我们不能将其索引为 FULLTEXT。我可能错过了格式化表格的一点......
无论如何,这是代码:
function backup_tables($DBH,$tables,$compression,$format) {
$DBH->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL );
//Script Variables
$BACKUP_PATH = DUMP;
$date = date("Y-m-d");
$olddir = getcwd();
chdir($BACKUP_PATH);
if(!file_exists($date)) {
echo "<font color=red>Created ‘".$date."’ folder</font><br />";
$cmd = "mkdir ".$date;
exec($cmd);
}
chdir($date);
//array of all database field types which just take numbers
$numtypes = array('tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'float', 'double', 'decimal', 'real');
//get all of the tables
if(empty($tables)) {
$pstm1 = $DBH->query('SHOW TABLES');
while($row = $pstm1->fetch(PDO::FETCH_NUM)) {
$tables[] = $row[0];
}
}
else {
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through the table(s)
echo "<font color=blue>Dumping tables to DB_DUMP:</font>";
echo "<ul>";
foreach($tables as $table) {
//create/open files
if($format == "csv") {
$filename = $table.".csv";
$handle = fopen($filename,"w");
}
else {
if($compression) {
$filename = $table.".sql.gz";
$zp = gzopen($filename,"wb9");
}
else {
$filename = $table.".sql";
$handle = fopen($filename,"w");
}
}
echo "<li><small><font color=blue>".$filename."</font>";
$result = $DBH->query("SELECT * FROM $table");
$num_fields = $result->columnCount();
$num_rows = $result->rowCount();
$return = "";
$return .= 'DROP TABLE IF EXISTS `'.$table.'`;';
//table structure
$pstm2 = $DBH->query("SHOW CREATE TABLE $table");
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);
$return .= "\n\n".$ifnotexists.";\n\n";
if($format <> "csv") {
if($compression) gzwrite($zp, $return);
else fwrite($handle,$return);
}
$return = "";
//insert values
if($num_rows) {
$return = 'INSERT INTO `'."$table"."` (";
$pstm3 = $DBH->query("SHOW COLUMNS FROM $table");
$count = 0;
$type = array();
while($rows = $pstm3->fetch(PDO::FETCH_NUM)) {
if(stripos($rows[1], '(')) {
$type[$table][] = stristr($rows[1], '(', true);
}
else $type[$table][] = $rows[1];
$return .= "`".$rows[0]."`";
$count++;
if($count < ($pstm3->rowCount())) {
$return .= ", ";
}
}
$return .= ")".' VALUES';
if($format <> "csv") {
if($compression) gzwrite($zp, $return);
else fwrite($handle,$return);
}
$return = "";
}
$count = 0;
while($row = $result->fetch(PDO::FETCH_NUM)) {
if($format <> "csv") $return = "\n\t(";
for($j=0; $j < $num_fields; $j++) {
//$row[$j] = preg_replace("\n","\\n",$row[$j]);
if(isset($row[$j])) {
if($format == "csv") $return .= '"'.$row[$j].'"';
else {
//if number, take away "". else leave as string
if((in_array($type[$table][$j],$numtypes)) && (!empty($row[$j])))
$return .= $row[$j];
else
$return .= $DBH->quote($row[$j]);
}
}
else {
if($format == "csv") $return .= '';
else $return .= 'NULL';
}
if($j < ($num_fields-1)) $return .= ',';
}
$count++;
if($format == "csv") $return .= "\n";
else {
if($count < ($result->rowCount()))
$return .= "),";
else $return .= ");";
}
if($format == "csv") fwrite($handle,$return);
else {
if($compression) gzwrite($zp, $return);
else fwrite($handle,$return);
}
$return = "";
}
$return = "\n\n-- ------------------------------------------------ \n\n";
echo " (".$count." records)";
if($format <> "csv") {
if($compression) gzwrite($zp, $return);
else fwrite($handle,$return);
}
$return = "";
$error1 = $pstm2->errorInfo();
$error2 = $pstm3->errorInfo();
$error3 = $result->errorInfo();
echo $error1[2];
echo $error2[2];
echo $error3[2];
if($format == "csv") fclose($handle);
else {
if($compression) gzclose($zp);
else fclose($handle);
}
$filesize = filesize($filename);
echo " - ".$filesize." bytes</small></li>";
}
echo "</ul>";
chdir($olddir);
return;
}