Exportar e importar BD de mysql con PHP

Imagen de omegajack

Forums: 

Hola a todos, me enfrento con un problema que quizas mi inexperiencia me hace no poder solucionar del todo, consiste en un apartado que permita importar y exportar bases de datos de mysql.

Hasta el momento tengo el script para exportar la base de datos(el cual encontre en la web), le hice unas pequeñas modificaciones y funciona perfectamente. Es el siguiente:

<?php
$con_base=mysql_connect("localhost","root","");
$base="sici";
$tablas=mysql_query("show tables from $base;",$con_base);
$texto.="create database if not exists $base;\n";
$texto.="use $base;\n";
while($tabla=mysql_fetch_array($tablas))
{
$mitabla=$tabla[0];
$creates=mysql_query("show create table $base.$mitabla;",$con_base);
while($create=mysql_fetch_array($creates))
{
$texto.=$create[1].";\n";
$datos=mysql_query("select * from $base.$mitabla;",$con_base);
$campos=mysql_num_fields($datos);
$regs=mysql_num_rows($datos);
for($i=0;$i<$regs;$i++)
{
$inserta="insert into $mitabla(";
for($j=0;$j<$campos;$j++)
{
$nombre=mysql_field_name($datos,$j);
$inserta.="$nombre,";
}
$inserta=substr($inserta,0,strlen($inserta)-1).") values(";
for($j=0;$j<$campos;$j++)
{
$tipo=mysql_field_type($datos,$j);
$valor=mysql_result($datos,$i,$j);
switch($tipo)
{
case "string":
case "date":
case "time":
$valor="'$valor'";
break;
}
$inserta.="$valor,";
}
$inserta=substr($inserta,0,strlen($inserta)-1).");";
$texto.=$inserta."\n";
}
}
$texto.="\n";
}
$archivo= "SICI.sql";
header("Content-disposition: attachment;filename=$archivo");
header("Content-Type: text/plain");
echo $texto;
?>

El problema esta cuando quiero restaurar la base de datos, he leido en internet y hay algunos scripts que funcionan usando el ejecutable de mysql, es decir usan el comando "system" pero para lo que necesito no me es de utilidad, requiero hacerlo con las funciones de mysql que tiene php, he intentado algo como esto:

<?php
$url="http://localhost/SICI/tmp/SICI.sql";
$nowhost= "localhost";
$nowdatabase= "sici";
$nowuser= "root";
$nowpass= "";

$link = mysql_connect($nowhost, $nowuser, $nowpass);
$file_content = file($url);
foreach($file_content as $sql_line)
{
if(trim($sql_line) != "" && strpos($sql_line, "--") == false)
{
echo $sql_line.'
';
mysql_query($sql_line);
}
}

?>

Pero el problema es que solo crea la base de datos, no crea sus respectivas tablas, imaginemos que el archivo es el siguiente(el creado por el primer script)

create database if not exists sici;
use sici;
CREATE TABLE `usuarios` (
`id` int(11) NOT NULL auto_increment,
`usuario` varchar(20) default NULL,
`password` varchar(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into usuarios(id,usuario,password) values(1,'alfredo','123');
insert into usuarios(id,usuario,password) values(2,'jose alfredo salazar','123');

El script de restauracion solamente crea la base de datos, es decir se queda en la segunda linea del archivo SQL. Si alguien tuvieses alguna sugerencia se la agradeceria muchisimo. De antemano gracias por tomarse el tiempo de leer lo que posteo. Saludos!

Solucionado

Imagen de omegajack

Jejejeje bueno yo aqui respondiendome a mi solito.... Bueno bueno el caso era que el problema no estaba en el script de restauracion, sino al de respaldo, es decir, en el primero, por que si observan el archivo sql que guarda lo guarda con "\n" es decir un enter a partir de CREATE TABLE, por lo que, en el script de restauracion al tratar de leer linea a linea se encontraba con un conflicto puesto que mysql finaliza siempre con ";". La solucion esta en hace que el script de respaldo a parttir de que comienza a definir los CREATE TABLE no lo guarde con espacios, es decir cada CREATE se defina en una sola linea para que pueda ejecutarse con el mysql_query. Al segundo script no le modifique nada, solo al primero, y quedo de la siguiente manera.

<?php
$con_base=mysql_connect("localhost","root","");
$base="sici";
$tablas=mysql_query("show tables from $base;",$con_base);
$texto_inicial.="create database if not exists $base;\n";
$texto_inicial.="use $base;\n";
while($tabla=mysql_fetch_array($tablas))
{
$mitabla=$tabla[0];
$creates=mysql_query("show create table $base.$mitabla;",$con_base);
while($create=mysql_fetch_array($creates))
{
$texto.=$create[1];
$texto=ereg_replace("\n"," ",$texto);
$datos=mysql_query("select * from $base.$mitabla;",$con_base);
$campos=mysql_num_fields($datos);
$regs=mysql_num_rows($datos);
for($i=0;$i<$regs;$i++)
{
$inserta="\ninsert into $mitabla(";
for($j=0;$j<$campos;$j++)
{
$nombre=mysql_field_name($datos,$j);
$inserta.="$nombre,";
}
$inserta=substr($inserta,0,strlen($inserta)-1).") values(";
for($j=0;$j<$campos;$j++)
{
$tipo=mysql_field_type($datos,$j);
$valor=mysql_result($datos,$i,$j);
switch($tipo)
{
case "string":
case "date":
case "time":
$valor="'$valor'";
break;
}
$inserta.="$valor,";
}
$inserta=substr($inserta,0,strlen($inserta)-1).");";
$texto.=$inserta;
}
}
$texto=$texto_inicial.$texto;
}
$archivo= "SICI.sql";
$texto=ereg_replace("CHARSET=latin1","CHARSET=latin1;",$texto);
header("Content-disposition: attachment;filename=$archivo");
header("Content-Type: text/plain");
echo $texto;
?>

Bien, espero esto le sirva a alguien, como a mi me va a servir ahora. Saludos

Seleccionar e importar con php una base msql

Hola se que el tema es un poco viejo, pero tu forma de exportar la base de datos me ayuda mucho.

Ahora bien el problema que tengo es que estoy haciendo un aplicación donde el usuario aparte de hacer un BackUP de la base (exportar), también podría importar la base de datos mediante un formulario seleccionando el fichero .sql y así cargarlo, remplazarlo o actualizar la base de datos en mysql.

Podrias decirme como hacer funcionar el script que tienes para seleccionar el archivo .sql e importar la base con PHP.

De ante mano muchas gracias.

Yo usaría mejor

Imagen de iknaxio

SELECT ... INTO OUTFILE para volcar los registros a un archivo y su complemento LOAD DATA INFILE para restaurarlo. O mysqldump!

"Transporta un puñado de tierra todos los días y construirás una montaña" - Confucio
floss.iknaxio.net

LOAD DATA IN FILE es para

Imagen de deathUser

LOAD DATA IN FILE es para cargar archivos tipo CSV por ejemplo, ya que puedes especificar los separadores de campo y de registro, pero si lo que tienes es un SQL, no queda de otra que parsear el archivo y ejecutar las consultas o grabar el archivo y ejecutar un:


mysql -u usuario -pclave base_de_datos < archivo.sql

Lo cual es muy peligroso dependiendo del usuario con el que se ejecute el sql sobre la base de datos, incluso la ejecución de sqls parseando el archivo SQL es peligrosa ya que te podrían hacer cualquier cosa que tenga permiso el usuario con el que se conectan a la base de datos ...

Para los que les preocupa un SQLInjection, pues esto es el valhala del SQLInjection

bye
;)

Sí, pero

Imagen de iknaxio

Sí es correcto, LOAD DATA solo es para archivos CSV, pero creo que para una carga web el formato CSV es más óptimo, ya que estás seguro de que sólo se van a ejecutar INSERT's en contraposición a tener un archivo SQL en donde alguien puede filtrar un DELETE o hasta un DROP.

Retiro si, la sugerencia de usar mysqldump para volcar a formato sql, ya que habría que tomar muchas precauciones que por lo general no se hacen.

De todas formas insisto en que con LOAD DATA es suficiente jejeje.

"Transporta un puñado de tierra todos los días y construirás una montaña" - Confucio
floss.iknaxio.net