Skip to content

Instantly share code, notes, and snippets.

@ricardodantas
Created December 4, 2012 04:05
Show Gist options
  • Save ricardodantas/4200479 to your computer and use it in GitHub Desktop.
Save ricardodantas/4200479 to your computer and use it in GitHub Desktop.
dbf2mysql.class.php
<?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("'","&apos;",$this->registro[$lugar]);
$this->registro[$lugar] = str_replace("\"","&quot;",$this->registro[$lugar]);
$this->registro[$lugar] = str_replace("`","&#096;",$this->registro[$lugar]);
$this->registro[$lugar] = str_replace("´","&acute;",$this->registro[$lugar]);
$this->registro[$lugar] = str_replace("\\","&#092;",$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