Created
December 4, 2012 04:05
-
-
Save ricardodantas/4200479 to your computer and use it in GitHub Desktop.
dbf2mysql.class.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
** Convert DBF files to MySQL file | |
** contact: http://gschimpf.com/ | |
** | |
** USAGE: | |
** $filename = "dir/file.dbf"; | |
** // Show the result sql | |
** dbf2mysql::mostrarSQL($filename); | |
** OR: | |
** // send a file.sql using header(); | |
** dbf2mysql::enviarSQL($filename); | |
** OR: | |
** //save a file.sql in actual folder | |
** dbf2mysql::guardarSQL($filename); | |
**/ | |
class dbf2mysql { | |
protected $archivoDBF = ""; | |
protected $nombre = ""; | |
protected $tamano = 0; | |
protected $cantidadCampos = 0; | |
protected $cantidadRegistros = 0; | |
protected $titulosCampos = Array(); | |
protected $salidaSQL = Array(); | |
protected $tiempoInicio = 0; | |
private function __construct($ficheroDBF) { | |
/* almacenamos el nombre de la tabla */ | |
$this->archivoDBF = $ficheroDBF; | |
/* obtenemos el nombre del fichero */ | |
$this->nombre = $this->getNombreOnly(); | |
/* obtenemos el tamano del fichero */ | |
$this->tamano = filesize($this->archivoDBF); | |
/* tomamos el tiempo de inicio */ | |
$this->tiempoInicio = $this->getFullTime(); | |
} | |
public static function mostrarSQL($archivo) { | |
/* creamos un objeto del tipo dbfFile */ | |
$dbf2sql = new dbf2mysql($archivo); | |
/* si se pudo convertir mostramos el resultado */ | |
if ($dbf2sql->convert()) | |
$dbf2sql->showSQL(True); | |
} | |
public static function enviarSQL($archivo) { | |
/* creamos un objeto del tipo dbfFile */ | |
$dbf2sql = new dbf2mysql($archivo); | |
/* si se pudo convertir enviamos el archivo */ | |
if ($dbf2sql->convert()) | |
$dbf2sql->sendSQL(); | |
} | |
public static function guardarSQL($archivo) { | |
/* creamos un objeto del tipo dbfFile */ | |
$dbf2sql = new dbf2mysql($archivo); | |
/* si se pudo convertir retornamos el resultado */ | |
if ($dbf2sql->convert()) | |
$dbf2sql->saveToFile(); | |
} | |
public static function getSQL($archivo) { | |
/* creamos un objeto del tipo dbfFile */ | |
$dbf2sql = new dbf2mysql($archivo); | |
/* si se pudo convertir retornamos el resultado */ | |
if ($dbf2sql->convert()) | |
return $dbf2sql->salidaSQL; | |
} | |
public function getName() { | |
return $this->fileName; | |
} | |
protected function getNombreOnly() { | |
/* obtenemos el nombre del fichero eliminando las carpetas anteriores al mismo */ | |
$nombreCompleto = explode("/", $this->archivoDBF); | |
$nombreCompleto = $nombreCompleto[count($nombreCompleto) - 1]; | |
/* eliminamos la extension del nombre. ej: fichero.dbf -> ficherodbf */ | |
$nombreCompleto = explode(".", $nombreCompleto); | |
$retorno = ""; | |
foreach($nombreCompleto AS $parteNombre) | |
$retorno .= $parteNombre; | |
return $retorno; | |
} | |
protected function getFullTime() { | |
$timeInicio = explode(" ",microtime()); | |
return $timeInicio[1] + $timeInicio[0]; | |
} | |
protected function sendSQL() { | |
/* esta funcion envia el fichero para descargar utilizando las cabeceras HEADER */ | |
/* envio el nombre del fichero */ | |
header("Content-Disposition: attachment; filename=" . $this->nombre . ".sql"); | |
/* envio el tipo de archivo que estoy enviando */ | |
header("Content-Type: application/octet-stream"); | |
/* enviamos el archivo */ | |
$this->showSQL(False); | |
} | |
protected function showSQL($enHTML = false) { | |
/* | |
esta funcion muestra la consulta SQL final | |
recorremos la salida y enviamos linea por linea | |
*/ | |
foreach($this->salidaSQL AS $lineaSQL) { | |
if ($enHTML) | |
echo "<BR/>\n$lineaSQL"; | |
else | |
echo "$lineaSQL\n"; | |
} | |
} | |
protected function saveToFile() { | |
$this->fileName = $this->nombre . ".sql"; | |
/* si el archivo ya existe se elimina */ | |
if (is_file($this->fileName)) { | |
echo "Ya existe otro fichero con el nombre '" . $this->getName() . "' en el directorio actual"; | |
exit; | |
} | |
/* abrimos el archivo */ | |
if ($file = @fopen($this->fileName,"w")) { | |
foreach($this->salidaSQL as $linea) | |
fputs($file, "$linea\n"); | |
fclose($file); | |
echo "El archivo se almaceno en el directorio actual con el nombre '". $this->getName() ."'"; | |
} else | |
echo "No se puede escribir en el directorio"; | |
} | |
protected function convert() { | |
/* verificamos que se posea la libreria para trabajar con ficheros dBase */ | |
if ($this->dBaseOk()) { | |
/* verificamos que el archivo exista */ | |
if (is_file($this->archivoDBF) AND is_readable($this->archivoDBF)) { | |
/* Si todo esta Ok abrimos el fichero para trabajar sobre el */ | |
$this->archivoDBF = dbase_open($this->archivoDBF,0); | |
/* obtenemos la cantidad de campos */ | |
$this->cantidadCampos = dbase_numfields($this->archivoDBF); | |
/* obtenemos la cantidad de registros */ | |
$this->cantidadRegistros= dbase_numrecords($this->archivoDBF); | |
/* obtenemos los titulos de los campos */ | |
$this->titulosCampos = dbase_get_header_info($this->archivoDBF); | |
/* convertimos el fichero DBF a SQL */ | |
return $this->convertir2sql(); | |
} else { | |
echo "El fichero '" . $this->nombre . "' no existe o no tiene permisos de lectura"; | |
return False; | |
} | |
} else { | |
echo "Se necesita la libreria 'dbase' para poder convertir ficheros DBF"; | |
return False; | |
} | |
} | |
protected function dBaseOk() { | |
/* con esta funcion verifico si existe la libreria necesaria para trabajar con ficheros DBF */ | |
/* obtengo las librerias compiladas en PHP */ | |
$utilidades = get_loaded_extensions(); | |
/* recorro las librerias para verificar si existe dbase */ | |
foreach (get_loaded_extensions() AS $libreria) | |
if (strtolower($libreria) == "dbase") | |
/* si existe retorno true */ | |
return True; | |
/* si llegue aqui es porque no existe. retorno false */ | |
return False; | |
} | |
protected function convertir2sql() { | |
/* creamos la cabecera del archivo SQL */ | |
$this->crearCabecera(); | |
/* creamos la tabla */ | |
if (!$this->crearTabla()) | |
/* si se produzco un error retornamos false */ | |
return False; | |
/* volvamos la tabla */ | |
if (!$this->crearRegistros()) | |
/* si se produzco un error retornamos false */ | |
return False; | |
/* cerramos el fichero DBF */ | |
if (!$this->cerrarDBF()) | |
/* si se produzco un error retornamos false */ | |
return False; | |
/* creamos el footer del archivo */ | |
$this->crearFooter(); | |
/* si llegamos aqui todo fue bien */ | |
return True; | |
} | |
protected function crearCabecera() { | |
$this->agregar("--"); | |
$this->agregar("-- HDS Converter 0.2 (2009-08-20)"); | |
$this->agregar("-- Contact to: gschimpf.com"); | |
$this->agregar("--"); | |
$this->agregar(""); | |
$this->agregar("/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;"); | |
$this->agregar("/*!40103 SET TIME_ZONE='+00:00' */;"); | |
$this->agregar("/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;"); | |
$this->agregar("/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;"); | |
$this->agregar("/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;"); | |
$this->agregar("/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;"); | |
$this->agregar(""); | |
} | |
protected function crearTabla() { | |
/* | |
creamos la cabecera con el nombre y el primer campo que sera la palabla 'cod' + el nombre de la tabla | |
ej: 'codNombretabla' | |
*/ | |
$nombreTabla = $this->nombre; | |
$codPrimario = "cod" . ucfirst($this->nombre); | |
/* creamos la linea inicial del CREATE TABLE */ | |
$this->cabeceraTabla = "CREATE TABLE IF NOT EXISTS $nombreTabla (`$codPrimario` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY"; | |
/* verificamos que alla tomado valores */ | |
if ($nombreTabla == "" OR $codPrimario == "cod") { | |
echo "La cabecera no se creo correctamente"; | |
return False; | |
} | |
/* recorremos los campos tomando el nombre de cada uno y su tipo */ | |
for ($i = 0; $i < $this->cantidadCampos; $i++) { | |
/* obtenemos los datos campo */ | |
$campo = $this->titulosCampos[$i]; | |
/* obtenemos el nombre desde los datos campo */ | |
$tituloCampo = strtolower($campo['name']); | |
/* obtenemos el tipo desde los datos campo */ | |
$tipoCampo = $this->getTipoCampo($campo['type']); | |
/* verificamos que alla tomado valores */ | |
if ($tituloCampo == "" OR $tipoCampo == "") { | |
echo "Uno de los campos no se creo correctamente"; | |
return False; | |
} | |
/* armamos el tipo de campo */ | |
$this->cabeceraTabla .= ", `$tituloCampo` $tipoCampo NULL"; | |
} | |
/* finalizamos la cabecera */ | |
$this->cabeceraTabla .= ");"; | |
/* cargamos la cabecera a la salida SQL y si se produzco un error retornamos false */ | |
$this->agregar($this->cabeceraTabla); | |
/* si llegamos hasta aqui todo va Ok */ | |
return True; | |
} | |
protected function getTipoCampo($tipo) { | |
switch($tipo) { | |
case 'number': | |
$tipo = 'int(11)'; | |
break; | |
case 'date': | |
$tipo = 'date'; | |
break; | |
case 'character': | |
$tipo = 'varchar(250)'; | |
break; | |
case 'boolean': | |
$tipo = 'binary(1)'; | |
break; | |
case 'memo': | |
$tipo = 'longtext'; | |
break; | |
} | |
return $tipo; | |
} | |
protected function crearRegistros() { | |
/* agregamos una cabecera */ | |
$this->crearCabeceraVolcado(); | |
/* agregamos la linea para realizar el bloqueo de la tabla */ | |
$this->bloquearTabla(); | |
/* volvamos los registros */ | |
if (!$this->volcarRegistros()) | |
/* si se produzco un error retornamos false */ | |
return False; | |
/* desbloqueamos de la tabla */ | |
$this->desbloquearTabla(); | |
/* si llegamos hasta aqui todo va Ok */ | |
return True; | |
} | |
protected function crearCabeceraVolcado() { | |
/* ponemos una cabecera de la tabla */ | |
$this->agregar(""); | |
$this->agregar("--"); | |
$this->agregar("-- Volcando datos para la tabla " . $this->nombre); | |
$this->agregar("--"); | |
$this->agregar(""); | |
} | |
protected function volcarRegistros() { | |
/* recorremos los registros */ | |
for ($i = 1; $i <= $this->cantidadRegistros; $i++) { | |
/* creamos la linea INSERT. Usamos IGNORE para evitar problemas de registros repetidos */ | |
$this->crearLineaInsert(); | |
/* obtengo el valor del registro */ | |
if (!$this->obtenerRegistro($i)) | |
/* si se produzco un error retornamos false */ | |
return False; | |
/* por cada registro tenemos que recorrer todos los campos */ | |
for ($j = 0; $j < $this->cantidadCampos; $j++) { | |
/* removemos los caracteres raros del registro */ | |
$this->removerCaracteres($j); | |
/* agregamos el campo a la linea INSERT */ | |
$this->agregarItem($j); | |
} | |
/* siempre queda una cadena ', ' de mas. La eliminamos */ | |
$this->eliminarSobra(); | |
/* finalizamos la linea INSERT */ | |
$this->finalizarInsert(); | |
/* agregamos la linea INSERT a la salida */ | |
$this->agregar($this->lineaInsert); | |
} | |
/* si llegamos hasta aqui todo va Ok */ | |
return True; | |
} | |
protected function crearLineaInsert() { | |
$this->lineaInsert = "INSERT IGNORE INTO `" . $this->nombre . "` VALUES (Null,"; | |
} | |
protected function obtenerRegistro($lugar) { | |
$this->registro = dbase_get_record($this->archivoDBF,$lugar); | |
if (!$this->registro) { | |
/* si se produzco un error retornamos false */ | |
echo "No se pudo obtener el registro"; | |
return False; | |
} | |
return True; | |
} | |
protected function removerCaracteres($lugar) { | |
switch ($this->titulosCampos[$lugar]['type']) { | |
case "character": | |
case "memo": | |
/* si el tipo de dato es alfanumerico convertimos los posibles caracteres que afecten */ | |
/* convertimos los apostrofes, acentos y barras invertidas */ | |
$this->registro[$lugar] = str_replace("'","'",$this->registro[$lugar]); | |
$this->registro[$lugar] = str_replace("\"",""",$this->registro[$lugar]); | |
$this->registro[$lugar] = str_replace("`","`",$this->registro[$lugar]); | |
$this->registro[$lugar] = str_replace("´","´",$this->registro[$lugar]); | |
$this->registro[$lugar] = str_replace("\\","\",$this->registro[$lugar]); | |
/* convertimos los caracteres raros a caracteres HTML */ | |
$this->registro[$lugar] = strtr($this->registro[$lugar], get_html_translation_table(HTML_ENTITIES)); | |
/* transformamos los enter en <BR> */ | |
$this->registro[$lugar] = nl2br($this->registro[$lugar]); | |
/* eliminamos los espacios en blanco de mas */ | |
$this->registro[$lugar] = trim($this->registro[$lugar]); | |
break; | |
case "date": | |
/* si el tipo de dato es fecha le damos formato para MySQL */ | |
return $this->agruparFecha($lugar); | |
break; | |
} | |
} | |
protected function agregarItem($lugar) { | |
/* agregamos el item a la cadena INSERT */ | |
switch ($this->titulosCampos[$lugar]['type']) { | |
case "character": | |
case "memo": | |
case "date": | |
/* si el tipo de dato es alfanumerico lo almacenamos entre comillas '' */ | |
$this->lineaInsert .= "'" . $this->registro[$lugar] . "', "; | |
break; | |
default: | |
/* si el tipo de registro no es alfanumerico almacenamos el valor en bruto */ | |
$this->lineaInsert .= $this->registro[$lugar] . ", "; | |
break; | |
} | |
} | |
protected function agruparFecha($lugar) { | |
/* separamos el ano mes y dia de la fecha para convertirlo en MySQL. ej: '20090201' -> '2009-02-01' */ | |
$ano = substr($this->registro[$lugar],0,4); | |
$mes = substr($this->registro[$lugar],4,2); | |
$dia = substr($this->registro[$lugar],6,2); | |
/* armamos la cadena de fecha en MySQL */ | |
$validar = "$ano-$mes-$dia"; | |
/* eliminamos los espacios y el caracter '-' */ | |
$validar = str_replace("-","",$this->registro[$lugar]); | |
$validar = str_replace(" ","",$validar); | |
/* verificamos si tiene valor */ | |
if (strlen($validar) == 8) { | |
/* si tiene un valor verificamos si es una fecha correcta */ | |
if (!checkdate($mes,$dia,$ano)) { | |
/* si no es una fecha correcta mostramos un error y retornamos false */ | |
echo "La fecha del registro $lugar no es valida. Valor: '" . $this->registro[$lugar] . "'"; | |
return False; | |
} else { | |
/* si es correcta retornamos true */ | |
$this->registro[$lugar] = "$ano-$mes-$dia"; | |
return True; | |
} | |
} elseif (strlen($validar) == 0) { | |
/* si no tiene valor retornamos true */ | |
$this->registro[$lugar] = ""; | |
return True; | |
} else { | |
/* si tiene algun valor que no es de 8 digitos es una fecha incorrecta */ | |
echo "La fecha del registro $lugar no es valida. Valor: '" . $this->registro[$lugar] . "'"; | |
return False; | |
} | |
} | |
protected function eliminarSobra() { | |
/* eliminamos la coma y espacio ', ' sobrante que queda en la cadena */ | |
$this->lineaInsert = substr($this->lineaInsert,0,(strlen($this->lineaInsert) - 2)); | |
} | |
protected function finalizarInsert() { | |
/* cerramos el parentesis de la cadena INSERT */ | |
$this->lineaInsert .= ");"; | |
} | |
protected function cerrarDBF() { | |
/* cerramos la tabla */ | |
if (!dbase_close($this->archivoDBF)) | |
return False; | |
return True; | |
} | |
protected function bloquearTabla() { | |
/* agregamos una linea para que se realize el bloqueo de la tabla */ | |
$this->agregar("LOCK TABLES `" . $this->nombre . "` WRITE;"); | |
} | |
protected function desbloquearTabla() { | |
/* agregamos una linea para desbloquear la tabla */ | |
$this->agregar("UNLOCK TABLES;"); | |
} | |
protected function crearFooter() { | |
$this->agregar("/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;"); | |
$this->agregar(""); | |
$this->agregar("/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;"); | |
$this->agregar("/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;"); | |
$this->agregar("/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;"); | |
$this->agregar("/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;"); | |
$this->agregar(""); | |
$this->agregar("-- Conversion finalizada. " . date("Y-m-d H:i:s")); | |
$this->agregar("-- Duracion de la conversion: " . $this->tiempoTotal()); | |
} | |
protected function tiempoTotal() { | |
$this->tiempoInicio = $this->getFullTime() - $this->tiempoInicio; | |
return number_format($this->tiempoInicio,4,",",".") . " segundos"; | |
} | |
protected function agregar($linea) { | |
/* agregamos una linea a la salida SQL */ | |
$this->salidaSQL[] = $linea; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment