Backup do MySQL via PHP

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

[ Hits: 22.285 ]

Homepage: https://www.instagram.com/alexabolada/

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

Script SQL para banco de sistemas de postagens de artigos 1.0

Banco de Dados xD

De data para date

protegendo suas páginas de maneira eficiente

Classe PHP para acesso a bancos de dados em MySQL


  

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