Backup do MySQL via PHP

Publicado por Fábio Berbert de Paula 25/07/2003

[ Hits: 22.426 ]

Homepage: https://fabio.automatizando.dev

Download sql_and_zip.zip




Este script é usado para gerar um backup de tabelas de um banco de dados MySQL. A saída ainda é compactada no formato ZIP e aparece como janela de download no navegador. Parte do código foi extraída do phpMyAdmin. A classe utilizada para zipar o arquivo encontra-se no link para download.

  



Esconder código-fonte

<?
/*
Programa usado para fazer o dump de uma base de dados do MySQL

Por: Fabio Berbert de Paula <fabio@vivaolinux.com.br>
     Rio de Janeiro, 26 de Novembro de 2002
*/

// vou usar a classe phpzip.inc.php
require 'phpzip.inc.php';

// variaveis globais (configure aqui) -------------------------

// variaveis de banco de dados
$db_name    = 'nome_banco_dados';
$hostdb     = 'localhost';
$userdb     =  'usuario';
$passdb     = 'senha';
// as tabelas que quero
$tabelas = array ('tabela1','tabela2', 'tabela3'); 
$tempdir = "/tmp"; // diretorio temporario
$filename = 'sql.'.time().'.txt';

// variaveis do sistema
$incluir_insert = 1; // imprime os INSERT's tambem

// ----------------------------------------------------
// BLOCO PRINCIPAL
// conectar ao banco de dados
$con = mysql_pconnect($hostdb,$userdb,$passdb);
mysql_select_db($db_name);

// imprimir tipo do documento na tela

// imprimir o dump do banco de dados
chdir($tempdir);
$fp = fopen($filename,"w"); 
for ($x=0; $x<count($tabelas); $x++) {
   $saida = getTableDef($db_name, $tabelas[$x], "\n");
   fputs($fp,$saida."\n\n");

   if ($incluir_insert) {
      getTableContentFast($db_name, $tabelas[$x], '', '');
      fputs($fp,"\n\n");
   }
}
fclose($fp);

// gerar o arquivo zipado
$zipname = ereg_replace("txt$","zip",$filename);
$zip = new PHPZip();
$files[]=$filename;
$zip -> Zip($files, $zipname);

$tamanho = filesize($zipname);

// imprimir arquivo p/ download
header("Content-Type: application/zip");
header("Content-Length: $tamanho");
header("Content-Disposition: attachment; filename=$zipname");
header("Content-Transfer-Encoding: binary");

// abrir e enviar o arquivo
$fp = fopen("$zipname", "r");
fpassthru($fp);
fclose($fp);

// remover os arquivos temporarios
unlink($filename);
unlink($zipname);

// FIM DO PROGRAMA
// --------------------------------------------------------


// --------------------------------------------------------
// PROCEDIMENTOS - Baseado no csdigo do phpmyadmin
function sqlAddslashes($a_string = '', $is_like = FALSE) {
  if ($is_like) {
    $a_string = str_replace('\\', '\\\\\\\\', $a_string);
  } else {
    $a_string = str_replace('\\', '\\\\', $a_string);
  }
  $a_string = str_replace('\'', '\\\'', $a_string);

  return $a_string;
} // end of the 'sqlAddslashes()' function


function backquote($a_name, $do_it = TRUE) {
  if ($do_it && PMA_MYSQL_INT_VERSION >= 32306 && !empty($a_name) 
      && $a_name != '*') {

     if (is_array($a_name)) {
        $result = array();
        reset($a_name);
        while(list($key, $val) = each($a_name)) {
           $result[$key] = '`' . $val . '`';
        }
        return $result;
     } else {
        return '`' . $a_name . '`';
     }
  } else {
     return $a_name;
  }
} // end of the 'backquote()' function

/**
* Returns $table's CREATE definition
*
* @param   string   the database name
* @param   string   the table name
* @param   string   the end of line sequence
*
* @return  string   the CREATE statement on success
*
* @global  boolean  whether to add 'drop' statements or not
* @global  boolean  whether to use backquotes to allow the use of special
*                   characters in database, table and fields names or not
*
* @see     PMA_htmlFormat()
*
* @access  public
*/
function getTableDef($db, $table, $crlf) {
   global $drop;
   global $use_backquotes;
   global $con;

   $schema_create = '';
   if (!empty($drop)) {
      $schema_create .= 'DROP TABLE IF EXISTS ' . 
      backquote($table) . ';' . $crlf;
   }

   // For MySQL < 3.23.20
   $schema_create .= 'CREATE TABLE ' . 
   backquote($table) . ' (' . $crlf;

   $local_query   = 'SHOW FIELDS FROM ' . backquote($table) . ' FROM ' 
   . backquote($db);

   $result = mysql_query($local_query,$con);

   while ($row = mysql_fetch_array($result)) {
      $schema_create     .= '   ' . 
      backquote($row['Field']) 
      . ' ' . $row['Type'];

      if (isset($row['Default']) && $row['Default'] != '') {
           $schema_create .= ' DEFAULT \'' . 
           sqlAddslashes($row['Default']) . '\'';
      }

      if ($row['Null'] != 'YES') {
           $schema_create .= ' NOT NULL';
      }

      if ($row['Extra'] != '') {
           $schema_create .= ' ' . $row['Extra'];
      }

      $schema_create     .= ',' . $crlf;
   } // end while

   mysql_free_result($result);
   $schema_create = ereg_replace(',' . $crlf . '$', '', $schema_create);

   $local_query = 'SHOW KEYS FROM ' . backquote($table) . ' FROM ' 
   . backquote($db);

   $result = mysql_query($local_query,$con);
   while ($row = mysql_fetch_array($result)) {
       $kname    = $row['Key_name'];
       $comment  = (isset($row['Comment'])) ? $row['Comment'] : '';
       $sub_part = (isset($row['Sub_part'])) ? $row['Sub_part'] : '';

       if ($kname != 'PRIMARY' && $row['Non_unique'] == 0) {
           $kname = "UNIQUE|$kname";
       }

       if ($comment == 'FULLTEXT') {
           $kname = 'FULLTEXT|$kname';
       }

       if (!isset($index[$kname])) {
           $index[$kname] = array();
       }

       if ($sub_part > 1) {
           $index[$kname][] = backquote($row['Column_name']) . '(' . $sub_part . ')';
       } else {
           $index[$kname][] = backquote($row['Column_name']);
       }
   } // end while
   mysql_free_result($result);

   while (list($x, $columns) = @each($index)) {
       $schema_create .= ',' . $crlf;
       if ($x == 'PRIMARY') {
          $schema_create .= '   PRIMARY KEY (';
       } else if (substr($x, 0, 6) == 'UNIQUE') {
          $schema_create .= '   UNIQUE ' . substr($x, 7) . ' (';
       } else if (substr($x, 0, 8) == 'FULLTEXT') {
          $schema_create .= '   FULLTEXT ' . substr($x, 9) . ' (';
       } else {
          $schema_create .= '   KEY ' . $x . ' (';
       }
       $schema_create .= implode($columns, ', ') . ')';
   } // end while

   $schema_create .= $crlf . ');';

   return $schema_create;
} // end of the 'getTableDef()' function

/**
* php >= 4.0.5 only : get the content of $table as a series of INSERT
* statements.
* After every row, a custom callback function $handler gets called.
*
* Last revision 13 July 2001: Patch for limiting dump size from
* vinay@sanisoft.com & girish@sanisoft.com
*
* @param   string   the current database name
* @param   string   the current table name
* @param   string   the 'limit' clause to use with the sql query
* @param   string   the name of the handler (function) to use at the end
*                   of every row. This handler must accept one parameter
*                   ($sql_insert)
*
* @return  boolean  always true
*
* @global  boolean  whether to use backquotes to allow the use of special
*                   characters in database, table and fields names or not
* @global  integer  the number of records
* @global  integer  the current record position
*
* @access  private
*
* @see     PMA_getTableContent()
*
* @author  staybyte
*/
function getTableContentFast($db, $table, $add_query = '', $handler) {
   global $use_backquotes;
   global $rows_cnt;
   global $current_row;
   global $con;
   global $fp;

  $local_query = 'SELECT * FROM ' . backquote($db) . '.' . backquote($table) 
  . $add_query;

  $result = mysql_query($local_query,$con);
  if ($result != FALSE) {
     $fields_cnt = mysql_num_fields($result);
     $rows_cnt   = mysql_num_rows($result);

     // Checks whether the field is an integer or not
     for ($j = 0; $j < $fields_cnt; $j++) {
         $field_set[$j] = backquote(mysql_field_name($result, $j), $use_backquotes);
         $type = mysql_field_type($result, $j);
         if ($type == 'tinyint' || $type == 'smallint' || 
             $type == 'mediumint' || $type == 'int' ||
             $type == 'bigint'  ||$type == 'timestamp') {
             $field_num[$j] = TRUE;
         } else {
             $field_num[$j] = FALSE;
         }
     } // end for

     // Sets the scheme
     if (isset($GLOBALS['showcolumns'])) {
         $fields = implode(', ', $field_set);
         $schema_insert = 'INSERT INTO ' . backquote($table)
         . ' (' . $fields . ') VALUES (';
     } else {
         $schema_insert = 'INSERT INTO ' . 
         backquote($table) . ' VALUES (';
     }

     $search = array("\x00", "\x0a", "\x0d", "\x1a"); //\x08\\x09, not required
     $replace      = array('{FONTE}', '\n', '\r', '\Z');
     $current_row  = 0;

     @set_time_limit($GLOBALS['cfg']['ExecTimeLimit']);

     // loic1: send a fake header to bypass browser timeout if data
     //        are bufferized - part 1
     if (!empty($GLOBALS['ob_mode']) || (isset($GLOBALS['zip']) 
         || isset($GLOBALS['bzip']) || isset($GLOBALS['gzip']))) {
         $time0 = time();
     }

     while ($row = mysql_fetch_row($result)) {
         $current_row++;
         for ($j = 0; $j < $fields_cnt; $j++) {
            if (!isset($row[$j])) {
                 $values[] = 'NULL';
            } else if ($row[$j] == '0' || $row[$j] != '') {
                 // a number
                 if ($field_num[$j]) {
                     $values[] = $row[$j];
                 } else {
                    // a string
                    $values[] = "'" . str_replace($search, $replace, 
                    sqlAddslashes($row[$j])) . "'";
                 }
           } else {
              $values[] = "''";
           } // end if
        } // end for

        // Extended inserts case
        if (isset($GLOBALS['extended_ins'])) {
            if ($current_row == 1) {
               $insert_line  = $schema_insert . implode(', ', $values) . ');';
            } else {
               $insert_line  = '(' . implode(', ', $values) . ');';
            }
        } else {
        // Other inserts case
           $insert_line = $schema_insert . implode(', ', $values) . ');';
        }
        unset($values);

        // Call the handler
        fputs($fp,$insert_line . "\n");

        // loic1: send a fake header to bypass browser timeout if data
        //        are bufferized - part 2
        if (isset($time0)) {
            $time1 = time();
            if ($time1 >= $time0 + 30) {
               $time0 = $time1;
               header('X-pmaPing: Pong');
            }
        } // end if
     } // end while
  } // end if ($result != FALSE)
  mysql_free_result($result);

  return TRUE;
} // end of the 'getTableContentFast()' function
?>

Scripts recomendados

Criando um Portal de Notícias baseado em PHP/MySQL

Conexão com MySQL O.O.

Classe eveQuery: Interação com banco de dados

Backup com php, usando mysql_dump

protegendo suas páginas de maneira eficiente


  

Comentários
[1] Comentário enviado por elisandroc em 08/10/2003 - 09:08h

tentei fazer o donwload do arquivo, mas ele aparece sem nada dentro, pq??

[2] Comentário enviado por Herr_Filip em 04/10/2005 - 09:50h

muito, muito bom! parabéns! era o que eu precisava!
Estou criando um script unico pra backup de tabelas MySQL, PostgreSQL (já criei um script php ;) e depois ele executa um "zip" de toda a pasta! valeu!!

[3] Comentário enviado por Ka®eka´s em 20/07/2007 - 16:37h

Uma duvida.

Achei mto interessante o script, mas como faço pra pegar todas as tabelas de meu db, mais de 30.

Abraço

[4] Comentário enviado por fabio em 20/07/2007 - 16:46h

Olá Kaeka,

Neste caso você pode fazer uma query com mysql_query() enviando o comando sql "SHOW TABLES", que irá te retornar a lista de tabelas do banco de dados. Jogue isso pra um array do PHP e boa. É só adaptar o script :)

Um abraço.

[5] Comentário enviado por cris_calmeida em 01/03/2010 - 10:46h

Bom dia! Eu adaptei este script para o servidor que uso. Está funcionando só que o script não termina o "insert" de todas as tabelas. Ele para na penúltima tabela. E fazendo o backup "manualmente" (pelo phpMyAdmin) o arquivo fica com aproximadamente 6MB. O que pode estar ocorrendo? Obrigada.

[6] Comentário enviado por removido em 29/10/2010 - 09:37h

Muito bom, funcionou perfeitamente

[7] Comentário enviado por comfaa em 03/05/2011 - 18:05h

boa noite galera do VOL
poxa, nao consegui usar a query com o SHOW TABLE

alguem poderia me ajudar :??

abraços, obrigao.

[8] Comentário enviado por rodprats em 25/04/2013 - 11:49h

Muito bom esse script, mas como eu adapto para ele puxar, como no PHPMYADMIN, as configurações das chaves estrangeiras?
Exemplo:

ALTER TABLE `pedidos`
ADD CONSTRAINT `FK_centrodecusto` FOREIGN KEY (`id_centrodecusto`) REFERENCES `centrodecusto` (`id`),
ADD CONSTRAINT `FK_classificacao_p` FOREIGN KEY (`classificacao`) REFERENCES `classificacao` (`id`),
ADD CONSTRAINT `FK_usuario` FOREIGN KEY (`id_usuario`) REFERENCES `usuarios` (`id`);

Este script faz backup das tabelas e suas chaves estrangeiras, mas nao aplica o ALTER TABLE. Sendo assim, o campo não faz referência a outra tabela obrigatoriamente.

Alguém pode me dar uma luz ? Obs.: Meu banco está como InnoDB e no PhpMyAdmin faz esse backup completo.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts