Backup de bases de datos MySQL con PHP

Este artículo muestra cómo realizar un backup parcial o completo de bases de datos MySQL utilizando tan sólo código PHP. Esto es muy útil por ejemplo cuando un cliente no nos facilita datos de acceso a la base de datos de una aplicación web y sólo disponemos de un acceso FTP, o cuando sí disponemos de los datos de la base de datos pero no podemos acceder a ésta a través de la red (sólo disponible en localhost) y tampoco podemos utilizar herramientas como mysqldump para respaldar la información porque no disponemos de privilegios para ello, o simplemente porque no tenemos acceso a una shell a la que conectarnos y ejecutar comandos.

diagrama-backup-mysql-php

En cualquiera de estos escenarios, simplemente copiando y ejecutando el script PHP Backup_Database.php que se muestra a continuación podríamos hacer un export completo o parcial (sólo algunas tablas) de la base de datos a un fichero que podremos descargar después desde la misma cuenta FTP. Normalmente las aplicaciones PHP disponen de un fichero de configuración tipo config.php o similar en el que podremos encontrar el usuario y contraseña de la base de datos si por ejemplo el cliente los ha olvidado, y normalmente también disponen de algún directorio con permisos suficientes para crear nuevos archivos (cache, tmp, temp, etc.), que es donde diremos a nuestro script Backup_Database.php que deje el fichero con el backup de la base de datos. El fichero .sql resultante de la ejecución del script Backup_Database.php tendrá un nombre del tipo db-backup-database-date-time.sql:

Estructura del nombre del fichero generado por Backup_Database.php:

~$ ls cache/*.sql
cache/db-backup-smf-2012-01-31-11-17-35.sql

Este fichero contendrá el código SQL necesario para reproducir la estructura y el contenido de la base de datos original en otra base de datos distinta mediante el comando mysql:

~$ mysql -p -u admin smf < db-backup-smf-2012-01-31-11-17-35.sql

Comando para restaurar la base de datos exportada.

 

Código fuente de Backup_Database.php

<!--?php 
/**
 * This file contains the Backup_Database class wich performs
 * a partial or complete backup of any given MySQL database
 * @author Daniel López Azaña <http://www.daniloaz.com-->
 * @version 1.0
 */

// Report all errors
error_reporting(E_ALL);

/**
 * Define database parameters here
 */
define("DB_USER", 'admin');
define("DB_PASSWORD", 'test_passwd');
define("DB_NAME", 'database_name');
define("DB_HOST", 'localhost');
define("OUTPUT_DIR", 'cache');
define("TABLES", '*');

/**
 * Instantiate Backup_Database and perform backup
 */
$backupDatabase = new Backup_Database(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$status = $backupDatabase->backupTables(TABLES, OUTPUT_DIR) ? 'OK' : 'KO';
echo "


Backup result: ".$status;

/**
 * The Backup_Database class
 */
class Backup_Database {
    /**
     * Host where database is located
     */
    var $host = '';

    /**
     * Username used to connect to database
     */
    var $username = '';

    /**
     * Password used to connect to database
     */
    var $passwd = '';

    /**
     * Database to backup
     */
    var $dbName = '';

    /**
     * Database charset
     */
    var $charset = '';

    /**
     * Constructor initializes database
     */
    function Backup_Database($host, $username, $passwd, $dbName, $charset = 'utf8')
    {
        $this->host     = $host;
        $this->username = $username;
        $this->passwd   = $passwd;
        $this->dbName   = $dbName;
        $this->charset  = $charset;

        $this->initializeDatabase();
    }

    protected function initializeDatabase()
    {
        $conn = mysql_connect($this->host, $this->username, $this->passwd);
        mysql_select_db($this->dbName, $conn);
        if (! mysql_set_charset ($this->charset, $conn))
        {
            mysql_query('SET NAMES '.$this->charset);
        }
    }

    /**
     * Backup the whole database or just some tables
     * Use '*' for whole database or 'table1 table2 table3...'
     * @param string $tables
     */
    public function backupTables($tables = '*', $outputDir = '.')
    {
        try
        {
            /**
            * Tables to export
            */
            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);
            }

            $sql = 'CREATE DATABASE IF NOT EXISTS '.$this->dbName.";\n\n";
            $sql .= 'USE '.$this->dbName.";\n\n";

            /**
            * Iterate tables
            */
            foreach($tables as $table)
            {
                echo "Backing up ".$table." table...";

                $result = mysql_query('SELECT * FROM '.$table);
                $numFields = mysql_num_fields($result);

                $sql .= 'DROP TABLE IF EXISTS '.$table.';';
                $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
                $sql.= "\n\n".$row2[1].";\n\n";

                for ($i = 0; $i < $numFields; $i++) 
                {
                    while($row = mysql_fetch_row($result))
                    {
                        $sql .= 'INSERT INTO '.$table.' VALUES(';
                        for($j=0; $j<$numFields; $j++) 
                        {
                            $row[$j] = addslashes($row[$j]);
                            $row[$j] = ereg_replace("\n","\\n",$row[$j]);
                            if (isset($row[$j]))
                            {
                                $sql .= '"'.$row[$j].'"' ;
                            }
                            else
                            {
                                $sql.= '""';
                            }

                            if ($j < ($numFields-1))
                            {
                                $sql .= ',';
                            }
                        }

                        $sql.= ");\n";
                    }
                }

                $sql.="\n\n\n";

                echo " OK" . "
";
            }
        }
        catch (Exception $e)
        {
            var_dump($e->getMessage());
            return false;
        }

        return $this->saveFile($sql, $outputDir);
    }

    /**
     * Save SQL to file
     * @param string $sql
     */
    protected function saveFile(&$sql, $outputDir = '.')
    {
        if (!$sql) return false;

        try
        {
            $handle = fopen($outputDir.'/db-backup-'.$this->dbName.'-'.date("Ymd-His", time()).'.sql','w+');
            fwrite($handle, $sql);
            fclose($handle);
        }
        catch (Exception $e)
        {
            var_dump($e->getMessage());
            return false;
        }

        return true;
    }
}

93 comentarios

  1. George_p 23/03/2012
    • daniloaz 24/03/2012
      • George_p 25/03/2012
      • George_p 27/03/2012
        • daniloaz 12/06/2012
  2. Salvo 09/06/2012
    • daniloaz 12/06/2012
  3. ankit 11/06/2012
  4. Jorge 09/07/2012
  5. vina 07/08/2012
    • daniloaz 07/08/2012
      • Burhan Ibrahimi 24/03/2015
  6. vina 07/08/2012
    • daniloaz 07/08/2012
  7. JOSE PASTOR 07/09/2012
    • daniloaz 03/10/2012
      • Pierre 25/11/2012
  8. Pierre 25/11/2012
    • daniloaz 27/11/2012
    • leonardo 05/09/2014
  9. Sergio N Hernandez 21/12/2012
  10. mazzoeth 23/01/2013
  11. Martin 05/02/2013
    • daniloaz 02/04/2013
  12. Genwons 18/02/2013
    • daniloaz 02/04/2013
      • bcehprx 22/04/2013
  13. John 09/03/2013
  14. Fernando 22/03/2013
    • daniloaz 02/04/2013
  15. Omar Hernandez 09/04/2013
  16. felix 09/07/2013
  17. alex 18/07/2013
  18. Jippie 11/08/2013
  19. Berdejo Humberto 14/08/2013
  20. Bruce 03/10/2013
  21. Rick Leijten 12/10/2013
  22. Roberto Carlos Garcia Andino 02/11/2013
  23. Anthony 19/11/2013
  24. Rachid 25/11/2013
  25. antonis 03/02/2014
    • daniloaz 06/02/2014
  26. Dinu 07/08/2014
  27. ibrahim 30/08/2014
  28. sawan 03/09/2014
  29. Rama 03/09/2014
  30. haji 16/09/2014
  31. Mitesh Patel 19/09/2014
  32. zarith 23/09/2014
  33. Francesco 23/09/2014
      • Francesco 24/09/2014
  34. Gene 26/09/2014
  35. Mark 09/10/2014
  36. pandorasoft 09/10/2014
  37. imran 13/10/2014
  38. Mr . Chien 31/10/2014
  39. Michelle Firstiant 07/11/2014
  40. Jean Letourneau 21/11/2014
  41. James 20/12/2014
  42. bok 11/01/2015
  43. Chris 18/01/2015
  44. anj 03/02/2015
  45. blender 06/02/2015
    • Mariana 11/08/2015
  46. Antonio Munguia 20/02/2015
  47. Renjit 16/03/2015
  48. aniket 24/03/2015
  49. Carlos Guzman 09/04/2015
  50. sanjay 15/04/2015
  51. dio 23/04/2015
  52. Nisan Rai 12/06/2015
  53. Michael 05/07/2015
  54. Mariana 11/08/2015
  55. Mariana 11/08/2015
  56. Sushil 17/08/2015
  57. MarPlo 12/09/2015
  58. rj 15/09/2015
  59. Diego Soto 28/01/2016
  60. mario 07/04/2016
  61. Jorge 12/04/2016
  62. Mohammed Umar 28/05/2016
  63. Joshy Francis 31/10/2016
  64. Jorge Alejandro 16/12/2016

¡Deja tu comentario!

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *