Foros del Web » Programando para Internet » PHP »

[APORTE] Clase Backup

Estas en el tema de [APORTE] Clase Backup en el foro de PHP en Foros del Web. Bien, ésta es la clase: Código PHP: <?php           /* Copyright Edgar Alexander Franco 2012 */           class  Backup  extends  ZipArchive      {         private  $Id ;                      // Identificador para el respaldo.          private  ...
  #1 (permalink)  
Antiguo 21/12/2012, 22:28
Avatar de xIamAlex  
Fecha de Ingreso: abril-2012
Ubicación: Venezuela
Mensajes: 118
Antigüedad: 7 años, 7 meses
Puntos: 23
[APORTE] Clase Backup

Bien, ésta es la clase:

Código PHP:
<?php
    
    
/* Copyright Edgar Alexander Franco 2012 */
    
    
class Backup extends ZipArchive
    
{
        private 
$Id;                     // Identificador para el respaldo.
        
private $BackupDate;            // Fecha del backup.
        
private $BackupTmpPath;            // Ruta del archivo .zip temporal del backup.
        
private $Tables;                // Tablas de la base de datos mysql.
        
private $iTables;                // Índice de Tablas.
        
private $MysqlBackupContent;    // Contenido del archivo .sql.
        
private $Error;                    // En caso de que no exista una Base de datos / Tabla / Directorio.
        
        
public $Statement;                // Requerido. Un procedimiento de la clase mysqli.
        
public $MysqlDatabaseName;        // Requerido. Nombre de la base de datos mysql.
        
public $Name;                    // Nombre para el backup (Por defecto es 'Backup').
        
public $Path;                    // Ruta dónde se gestionará el respaldo, si no se especifíca, se gestionará en la misma carpeta del script.
        
public $MysqlBackupName;        // Nombre para el archivo .sql (Por defecto es 'MysqlBackup').
        
        
public function Backup()
        {
            
$this->Id time();
            
$this->BackupDate date('d-m-Y H-i-s');
            
$this->Tables = array();
            
$this->iTables 0;
            
$this->Name 'Backup';
            
$this->Path '';
            
$this->MysqlBackupName "MysqlBackup";
            
$this->MysqlBackupContent "";
            
$this->Error "An error has ocurred, please remove the "$this->BackupTmpPath" file if exist and try again.";
        }
        
        public function 
Init()
        {
            
// Crea un archivo .zip y establece su ruta.
            
            
$this->BackupTmpPath $this->Path$this->Name'-'$this->Id'.zip';
            
$this->open($this->BackupTmpPathZIPARCHIVE::CREATE);
        }
        
        public function 
addTable($Table)
        {
            
// Agrega una tabla mysql a respaldar.
            
            
$this->Tables$this->iTables ] = $Table;
            
$this->iTables++;
        }
        
        public function 
addFolder($FolderPath$DestinationPath)
        {
            
/*
            * Agrega un directorio a respaldar (A excepción de subdirectorios).
            * Primero validamos el directorio a respaldar.
            */
            
            
if(!is_dir($FolderPath))
            {
                die(
$this->Error);
            }
            
            
// Abrimos el directorio a respaldar agregamos el directorio al archivo .zip.
            
            
$Dir dir($FolderPath);
            
$this->addEmptyDir($DestinationPath);
            
            while(
$File $Dir->read())
            {
                
$FilePath $FolderPath$File;
                
                
// Comprobamos que no sea otro directorio.
                
                
if($File != '.' && $File != '..' && !is_dir($FilePath))
                {
                    
// Agregamos el archivo al .zip.
                    
                    
$this->addFile($FilePath$DestinationPath'/'$File);
                }
            }
        }
        
        public function 
generateMysqlBackup()
        {
            
// Cabecera del archivo.
            
            
$this->MysqlBackupContent .= "-- Mysql Backup: "$this->Id" / "$this->BackupDate".";
            
            foreach(
$this->Tables as $Table)
            {
                
/*
                * Primero consultamos todos los datos de la tabla actual para
                * verificar si hay registros.
                *
                * Si hay se crea un INSERT dentro del cuerpo del archivo, 
                * caso contrario se siguen evaluándo las otras tablas.
                */
                
                
$this->Statement->prepare('SELECT * FROM '$Table) or die($this->Error);
                
$this->Statement->execute();
                
$ResultSet $this->Statement->get_result();
                
$ValuesArray $ResultSet->fetch_all();        // Obtenémos todos los registros de la tabla.
                
                
if($ResultSet->num_rows 0)
                {
                    
// Si entrámos es porque existen registros, así que procedemos a crear el INSERT.
                    
                    
$Fields "";    // Un string que concatena todos los campos de la tabla actual.
                    
$Values "";    // Un string que concatena todos los valores de la tabla actual.
                    
                    // Cabecera para el INSERT de la tabla actual.
                    
                    
$this->MysqlBackupContent .= "\r\n\r\n-- Backup for the table '"$Table"':";
                    
                    
// Consultamos los campos de la tabla INFORMATION_SCHEMA a través del nombre de la tabla actual y la base de datos especificada.
                    
                    
$this->Statement->prepare('SELECT column_name FROM INFORMATION_SCHEMA.columns WHERE table_name = ? AND table_schema = ?') or die($this->Error);
                    
$this->Statement->bind_param('ss'$Table$this->MysqlDatabaseName);
                    
$this->Statement->execute();
                    
                    
$ResultSet $this->Statement->get_result();
                    
$FieldsArray $ResultSet->fetch_all();        // Obtenémos todos los campos.
                    
                    // Concatenámos los campos en un solo string.
                    
                    
foreach($FieldsArray as $Field)
                    {
                        
$Fields .= $Field[0]. ", ";
                    }
                    
                    
// Concatenámos cada registro en un solo string.
                    
                    
foreach($ValuesArray as $Value)
                    {
                        
$Values .= "(";
                        
                        foreach(
$Value as $Val)
                        {
                            
/*
                            * No se respétan los tipos de datos del todo, 
                            * pero pienso que no hay ningún problema.
                            */
                            
                            
$Val mysql_real_escape_string($Val);
                            
                            if(
$Val == '')
                            {
                                
// Si está vacío es asignado a NULL.
                                
                                
$Values .= "NULL, ";
                            }
                            else
                            {
                                if(
$Val == '0' || $Val == '1')
                                {
                                    
/*
                                    * Si es 0 o 1 lo asignamos como un tipo de dato numérico 
                                    * para evitar problemas con campos binarios (bit, tinyint).
                                    */
                                    
                                    
$Values .= $Val", ";
                                }
                                else
                                {
                                    
// Del resto es una cadena de caractéres.
                                    
                                    
$Values .= "'"$Val"', ";
                                }
                            }
                        }
                        
                        
$Values substr($Values0, -2);
                        
$Values .= "), ";
                    }
                    
                    
$Fields substr($Fields0, -2);
                    
$Values substr($Values0, -2);
                    
                    
// Terminámos el INSERT.
                    
                    
$this->MysqlBackupContent .= "\r\n\r\nINSERT INTO "$Table" ("$Fields") VALUES "$Values";";
                    
                    
// Hacémos una pequeña pausa para optimizar el proceso.
                    
                    
time_nanosleep(0100000000); // Exáctamente 10 milisegundos
                
}
                else
                {
                    
// Sino la tabla está vacía.
                    
                    
$this->MysqlBackupContent .= "\r\n\r\n-- Table '"$Table"' is empty.";
                }
            }
            
            
// Agregámos el archivo .sql al archivo de respaldo .zip.
            
            
$this->addFromString($this->MysqlBackupName'-'$this->BackupDate'.sql'$this->MysqlBackupContent);
        }
        
        public function 
SaveAndGet()
        {
            
// Ya cerramos el archivo .zip.
            
            
$this->close();
            
            
// Obtenémos el contenido del archivo .zip.
            
            
$BackupName $this->Name'-'$this->BackupDate'.zip';
            
$BackupContent file_get_contents($this->BackupTmpPath);
            
$BackupLength strlen($BackupContent);
            
            
// Eliminamos el archivo .zip del servidor.
            
            
if(file_exists($this->BackupTmpPath))
            {
                
unlink($this->BackupTmpPath);
            }
            
            
// Se manda a descargar el respaldo.
            
            
header('Content-Type: application/octet-stream');
            
header('Content-Disposition: attachment; filename='$BackupName);
            
header('Content-Length: '$BackupLength);
            
            echo 
$BackupContent;
        }
    }
    
?>
Simplemente copien y peguen dentro de un archivo llamado Backup.php.

Luego para usarla aquí va un ejemplo:

Código PHP:
<?php
    
    
include('Backup.php');
    
    
// Crea tu objeto mysqli y seguido un procedimiento.
    
    
$Servidor 'localhost';
    
$Usuario 'Usuario';
    
$Contrasena 'Contraseña';
    
$BaseDeDatos 'TuBaseDeDatos';
    
    
    
$mysqli = new mysqli($Servidor$Usuario$Contrasena$BaseDeDatos);
    
$stmt $mysqli->stmt_init();
    
    
$backup = new Backup(); // Instancia la clase.
    
    
$backup->Statement $stmt// Pasa el procedimiento (Ésto es requerido).
    
$backup->MysqlDatabaseName $BaseDeDatos// También es requerido si vas a hacer un respaldo de tu bd.
    
$backup->Path ''// Opcional, no tiene gran importancia, es la ruta dónde se gestionará el fichero zip.
    
$backup->Name 'Respaldo'// Opcional, aquí defines el nombre del backup, de no ser así, se llamará 'Backup' por defecto.
    
$backup->MysqlBackupName 'Respaldo-Mysql'// También opcional, lo mismo que con el nombre, pero con el archivo .sql que se generará dentro de tu zip.
    
    
$backup->Init(); // Inicializa el backup DESPUÉS de configurarlo (Requerido).
    
    /*
    * Método addTable (string) : void (opcional)
    * 
    * Declara una tabla para luego respaldar sus registros.
    */
    
    
$backup->addTable('MiTabla1');
    
$backup->addTable('MiTabla2');
    
$backup->addTable('MiTabla3');
    
    
/*
    * Método generateMysqlBackup () : void (opcional)
    * 
    * Agréga un archivo .sql con el respaldo de todas las tablas mencionadas al fichero .zip.
    */
    
    
$backup->generateMysqlBackup();
    
    
/*
    * Método addFolder (string, string) : void (opcional)
    * 
    * Agrega un directorio completo desde una ruta hacia una carpeta en el .zip
    * Parámetro 1 -> De.
    * Parámetro 2 -> Hacia.
    *
    * Parámetro 2 -> RespaldoDirectorio1/Subdirectorio -> Ésto no funcionará.
    */
    
    
$backup->addFolder('Directorio1''RespladoDirectorio1');
    
$backup->addFolder('Directorio2''RespladoDirectorio2');
    
    
/*
    * Método SaveAndGet () : void (requerido)
    * 
    * Cierra el .zip y lo pone para descarga, siempre debe ir al final del proceso.
    */
    
    
$backup->SaveAndGet();
    
?>
__________________
Las personas quieren autos, casas, teléfonos, dinero, poder, ser famosos, parejas, en fin.. yo solo quiero ser libre y feliz.
  #2 (permalink)  
Antiguo 21/12/2012, 22:29
Avatar de xIamAlex  
Fecha de Ingreso: abril-2012
Ubicación: Venezuela
Mensajes: 118
Antigüedad: 7 años, 7 meses
Puntos: 23
Respuesta: [APORTE] Clase Backup

Buenas amigos del foro, ¿Cómo han estado? hoy les vengo a traer mi aporte a una clase que desarrollé y me tomó todo el día la hice para un sistema que estoy desarrollando pero decidí compartirla para aquellos que:

1 - Necesiten hacer un respaldo desde un script php.
2 - Quieran respaldar su base de datos Mysql. (Sólamente INSERTS)
3 - Quieran respaldar algún directorio.

Todo en un mismo paquete, simplemente construyen un objeto, agregan las tablas y/o directorios que desean respaldar y listo a descargar.

Requerimientos:

1 - Un procedimiento PDO (Prepared Statement).
2 - Especificar el nombre de su base de datos (Si desean hacer un respaldo de ésta).
3 - Especificar el nombre de las tablas a respaldar los INSERTS.
4 - Tener la tabla INFORMATION_SCHEMA de mysql.

En caso de que ocurra algún error, el script morirá pidiendo que se elimine el archivo .zip del backup en caso de que haya sido generado.

El motivo por el cuál la hice fue para que al momento de realizar un backup se me hiciera lo más cómodo posible, evitando tener que entrar al phpmyadmin y hacer mi respaldo sql o si necesitaba archivos como imágenes de perfil de mis usuarios tener que acceder vía FTP. En fin con ésta clase lo hago todo en un instante y desde mi Web, me esforcé mucho para que quedara lo más óptima posible, y también para que los datos SQL se registrarán correctamente.

Espero que le sea de utilidad a alguien más, si desean modificarla adelante, pero siempre y cuando dejen mis créditos, gracias y un saludo.
__________________
Las personas quieren autos, casas, teléfonos, dinero, poder, ser famosos, parejas, en fin.. yo solo quiero ser libre y feliz.
  #3 (permalink)  
Antiguo 21/12/2012, 22:53
Avatar de xIamAlex  
Fecha de Ingreso: abril-2012
Ubicación: Venezuela
Mensajes: 118
Antigüedad: 7 años, 7 meses
Puntos: 23
Respuesta: [APORTE] Clase Backup

En el método addFolder el directorio a respaldar siempre debe terminar en "/", es decir "Directorio1/", "Directorio2/", etc.
__________________
Las personas quieren autos, casas, teléfonos, dinero, poder, ser famosos, parejas, en fin.. yo solo quiero ser libre y feliz.

Etiquetas: backup, clase, mysql, sql, tabla, usuarios
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:06.