2010-10-26 27 views
34

que tienen dos *.sql archivos que uso cuando se crea una nueva base de datos del sitio web. El primer archivo crea todas las tablas. El segundo archivo llena algunos registros predeterminados. Me gustaría ejecutar estos archivos desde PHP. También uso Zend_Framework, si eso ayuda a lograr esto.ejecutar MySQL archivos * .sql en PHP

Información adicional

  1. no tengo acceso a la consola
  2. Estoy tratando de automatizar la generación de sitio desde dentro de nuestra aplicación.

SOLUCIÓN

Usando shell_exec() ...

$command = 'mysql' 
     . ' --host=' . $vals['db_host'] 
     . ' --user=' . $vals['db_user'] 
     . ' --password=' . $vals['db_pass'] 
     . ' --database=' . $vals['db_name'] 
     . ' --execute="SOURCE ' . $script_path 
; 
$output1 = shell_exec($command . '/site_db.sql"'); 
$output2 = shell_exec($command . '/site_structure.sql"'); 

... nunca lo hice obtener una salida útil, pero seguía some suggestions en another thread y finalmente tengo todo trabajo. Cambio al formato --option=value para los comandos y usé --execute="SOURCE ..." en lugar de < para ejecutar el archivo.

Además, nunca obtuve una buena explicación de la diferencia entre shell_exec() y exec().

+0

¿No puedes usar la consola? Es mucho más fácil ... –

+0

@Pekka - actualicé mi publicación – Sonny

+0

funcionó muy bien para mí en Linux. has probado en Windows xampp, pero duda de que va a trabajar :) – ethanpil

Respuesta

33

Esta pregunta aparece de vez en cuando. No hay una buena solución para ejecutar un script .sql directamente desde PHP. Hay casos límite en los que los enunciados comunes en un script .sql no se pueden ejecutar como sentencias SQL. Por ejemplo, la herramienta mysql tiene builtin commands que no son reconocidos por el servidor MySQL, p. CONNECT, USE y DELIMITER.

así que doy 1 a @Ignacio Vazquez-Abrams de answer. Debe ejecutar su script .sql en PHP invocando la herramienta mysql, por ejemplo con shell_exec().


Tengo este trabajo prueba:

$command = "mysql -u{$vals['db_user']} -p{$vals['db_pass']} " 
. "-h {$vals['db_host']} -D {$vals['db_name']} < {$script_path}"; 

$output = shell_exec($command . '/shellexec.sql'); 

La parte fundamental es que la opción de MySQL -p no debe ser seguido por un espacio.

también lo he escrito con la sintaxis de la interpolación de variables en lugar de tanto la concatenación de cadenas.


Ver también mis respuestas a estas preguntas relacionadas:

+0

Estoy probando la ruta shell_exec(), pero no encuentro ejemplos que especifiquen un archivo para ejecutar. Esto es lo que tengo hasta ahora: 'shell_exec ('mysql'. '-u'. $ Vals ['db_user']. '-p'. $ Vals ['db_pass']. '-D'. $ Vals [' db_name ']); ' – Sonny

+1

Has leído el archivo para ejecutar con la redirección de shell:' mysql ...

+0

Gracias Bill! He actualizado mi pregunta con respecto a dónde estoy en el proceso. Todavía no funciona y no puedo entender por qué. – Sonny

9

Tendrá que crear un analizador de SQL completa para este. Recomiendo usar la herramienta de línea de comandos mysql para esto en su lugar, invocándola externamente desde PHP.

0

Una sugerencia:

// connect to db. 
if (mysql_query("SOURCE myfile.sql")) { 

    echo "Hello Sonny"; 

} 
+0

Si esto funciona (dependerá de privilegios) se es definitivamente la mejor manera de ir. –

+0

¡Voy a probar esta ruta y ver si puedo hacer que funcione! – Sonny

+4

No, 'SOURCE' es una herramienta incorporada de mysql. No puede ejecutarlo como una consulta SQL. –

2

No se olvide de phpMyAdmin. Interfaz bastante sólida para interactuar con MySQL.

No sé si resuelve su problema, ya que no sé si se puede interactuar con él directamente desde el código, pero sólo quería tirar por ahí.

+0

Buena sugerencia también. Al analizar los volcados de mySQL en puro PHP * apesta *, phpMyAdmin le quita el problema (aunque no es automatizable). –

12

Esto es lo que yo uso:


function run_sql_file($location){ 
    //load file 
    $commands = file_get_contents($location); 

    //delete comments 
    $lines = explode("\n",$commands); 
    $commands = ''; 
    foreach($lines as $line){ 
     $line = trim($line); 
     if($line && !startsWith($line,'--')){ 
      $commands .= $line . "\n"; 
     } 
    } 

    //convert to array 
    $commands = explode(";", $commands); 

    //run commands 
    $total = $success = 0; 
    foreach($commands as $command){ 
     if(trim($command)){ 
      $success += (@mysql_query($command)==false ? 0 : 1); 
      $total += 1; 
     } 
    } 

    //return number of successful queries and total number of queries found 
    return array(
     "success" => $success, 
     "total" => $total 
    ); 
} 


// Here's a startsWith function 
function startsWith($haystack, $needle){ 
    $length = strlen($needle); 
    return (substr($haystack, 0, $length) === $needle); 
} 
+0

¡Me encanta, funciona muy bien! –

+5

Hay casos límite en los que esto fallará, y no con un mensaje de error sino con un comportamiento (potencialmente) inesperado. Por ejemplo, los literales de cadenas multilínea en sus sentencias de SQL podrían comenzar con la cadena ''-'', o los literales de cadena podrían contener caracteres ';'. Si vas a seguir esta ruta, realmente deberías usar un analizador SQL completo. –

15
$commands = file_get_contents($location); 
$this->_connection->multi_query($commands); 
+5

Su solución funciona para 'mysqli'. Estoy usando PDO. Su respuesta me llevó a hacer una búsqueda, y encontré esto: http://stackoverflow.com/questions/6346674/pdo-support-for-multiple-queries-pdo-mysql-pdo-mysqlnd – Sonny

+0

Estoy usando mysqli y no puede hacer que esta solución funcione. $ commands simplemente vuelve como una cadena vacía. Para $ location probé tanto una ruta local relativa (el archivo de script está en la misma carpeta que el archivo php) como un hipervínculo completo. Obtengo el mismo resultado de cualquier manera. – Jimbo

5

Sé que soy muy tarde a la fiesta, pero ha sido un PHP Mini Admin salvavidas en un par de ocasiones. Básicamente es un PHPMyAdmin "lite" todo contenido en un archivo, por lo que no es necesario realizar instalaciones complicadas, solo cárguelo e inicie sesión. ¡Simples!

+0

¡Tantas votaciones ascendentes! –

1

Creé un script de migración con multi_query. Puede procesar exportaciones de mysqldump y phpmyadmin sin la herramienta de línea de comandos mysql. También hice un poco de lógica para procesar múltiples archivos de migración basados ​​en la marca de tiempo almacenada en DB como Rails. Sé que necesita más manejo de errores, pero actualmente hace el trabajo por mí.

Hay que ver: https://github.com/kepes/php-migration

creo que si no lo hace con la entrada del usuario proceso que sólo guiones realizados por los desarrolladores o herramientas de exportación se pueden utilizar de forma segura.

0

Para ejecutar la generación de tabla desde dentro de la aplicación, es posible que desee crear un archivo php que haga exactamente eso cuando lo ejecute.

$hostname = "localhost"; 
$database = "databasename"; 
$username = "rootuser"; 
$UserPassword = "password"; 

$myconnection = mysql_pconnect($hostname, $username , $UserPassword) or trigger_error(mysql_error(),E_USER_ERROR); 
mysql_connect($hostname , $username , $UserPassword) or die(mysql_error()); 
mysql_select_db($database) or die(mysql_error()); 

if (!$myconnection){ echo "Error connecting to database.\n";} 


$userstableDrop = " DROP TABLE IF EXISTS `users`"; 
$userstableCreate = " CREATE TABLE IF NOT EXISTS `users` (
`UserID` int(11) NOT NULL, 
    `User_First_Name` varchar(50) DEFAULT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=15" ; 

$userstableInsert = "INSERT INTO `users` (`UserID`, `User_First_Name`) VALUES 
(1, 'Mathew'), 
(2, 'Joseph'), 
(3, 'James'), 
(4, 'Mary')"; 

$userstableAlter1 = "ALTER TABLE `users` ADD PRIMARY KEY (`UserID`)"; 
$userstableAlter2 = " ALTER TABLE `users` MODIFY `UserID` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=15"; 

$createDb_sql = $userstableDrop; 
$insertSite = mysql_query($createDb_sql); 

$createDb_sql = $userstableCreate; 
$insertSite = mysql_query($createDb_sql); 

$createDb_sql = $userstableInsert; 
$insertSite = mysql_query($createDb_sql); 

$createDb_sql = $userstableAlter1; 
$insertSite = mysql_query($createDb_sql); 

$createDb_sql = $userstableAlter2; 
$insertSite = mysql_query($createDb_sql); 

echo "Succesful!"; 
mysql_close($myconnection); 
+0

Consulte [cómo responder] (http://stackoverflow.com/help/how-to-answer) preguntas en SO. – techspider

1

Puede utilizar esta secuencia de comandos para ejecutar los archivos de script de MySQL. Tendrá que configurar $ hostName, $ userName, $ password, $ dataBaseName, $ port y $ fileName, por supuesto.

<?php 

function parseScript($script) { 

    $result = array(); 
    $delimiter = ';'; 
    while(strlen($script) && preg_match('/((DELIMITER)[ ]+([^\n\r])|[' . $delimiter . ']|$)/is', $script, $matches, PREG_OFFSET_CAPTURE)) { 
    if (count($matches) > 2) { 
     $delimiter = $matches[3][0]; 
     $script = substr($script, $matches[3][1] + 1); 
    } else { 
     if (strlen($statement = trim(substr($script, 0, $matches[0][1])))) { 
     $result[] = $statement; 
     } 
     $script = substr($script, $matches[0][1] + 1); 
    } 
    } 

    return $result; 

} 

function executeScriptFile($fileName, $dbConnection) { 
    $script = file_get_contents($scriptFleName); 
    $statements = parseScript($script); 
    foreach($statements as $statement) { 
    mysqli_query($dbConnection, $statement); 
    } 
} 

$hostName = ''; 
$userName = ''; 
$password = ''; 
$dataBaseName = ''; 
$port = ''; 
$fileName = ''; 

if ($connection = @mysqli_connect($hostName, $userName, $password, $dataBaseName, $port)) { 
    executeScriptFile($fileName, $connection); 
} else { 
    die('Can not connect to MySQL'); 
} 
+0

Al escribir una respuesta a su propia pregunta, ¿podría publicar una explicación y un código? Sin una explicación, todavía no sabemos por qué se solucionó el problema sin estudiar un montón de código inútil. – Simon

+0

No fue mi propia pregunta. TC preguntó "Me gustaría ejecutar estos archivos desde PHP". Le di el guión de cómo hacer esto. Si no puede leer un fragmento de código tan pequeño (no hay mucho que estudiar, es demasiado pequeño y obvio), y si no necesita una solución, ¿por qué puede omitir mi respuesta en lugar de ser tan grosero? :) –

+1

No estoy tratando de ser grosero. Ver ese voto abajo (¿alguien más lo puso allí en caso de que pienses que soy yo)? Estoy tratando de decirte * por qué * lo estás obteniendo y sugerir lo que puedes hacer para obtener votos alternativos en su lugar. Solo estoy tratando de ayudar. también fue editado editado hace 3 minutos y ahora se ve mejor. Desafortunadamente para los recién llegados, los usuarios aquí esperan una respuesta (y una pregunta) fantásticas además de un código de trabajo. Es un truco. Una vez que lo tenga, podrá hacer buenas respuestas (y preguntas) y obtener votaciones. – Simon

Cuestiones relacionadas