Execução de arquivos MySQL * .sql em PHP

Eu tenho dois arquivos *.sql que eu uso ao criar um novo database do site. O primeiro arquivo cria todas as tabelas. O segundo arquivo preenche alguns registros padrão. Gostaria de executar esses arquivos a partir do PHP. Eu também uso o Zend_Framework, se isso ajudar a realizar isso.

Informação adicional

  1. Eu não tenho access ao console
  2. Estou tentando automatizar a geração de sites dentro do nosso aplicativo.

SOLUÇÃO

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 obtive resultados úteis, mas segui algumas sugestões em outro tópico e finalmente consegui tudo funcionando. Eu --execute="SOURCE ..." para o formato --option=value para os comandos e usado --execute="SOURCE ..." vez de < para executar o arquivo.

Além disso, nunca obtive uma boa explicação da diferença entre shell_exec() e exec() .

Esta questão surge de tempos em tempos. Não há uma boa solução para executar um script .sql diretamente do PHP. Existem casos de ponta em que as instruções comuns em um script .sql não podem ser executadas como instruções SQL. Por exemplo, a ferramenta mysql possui comandos básicos que não são reconhecidos pelo servidor MySQL, por exemplo, CONNECT , USE e DELIMITER .

Então dou +1 para a resposta de @Ignacio Vazquez-Abrams. Você deve executar seu script .sql em PHP invocando a ferramenta mysql , por exemplo, com shell_exec() .


Eu fiz o teste funcionar:

 $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'); 

A parte crucial é que a opção -p do MySQL não deve ser seguida por um espaço.

Eu também escrevi com a syntax de interpolação variável ao invés de tanta concatenação de string.


Veja também minhas respostas a estas questões relacionadas:

  • Carregando arquivos .sql dentro do PHP
  • é possível chamar um script sql de um procedimento armazenado em outro script sql?
  • PHP: várias consultas SQL em uma declaração mysql_query
 $commands = file_get_contents($location); $this->_connection->multi_query($commands); 

Aqui está o que eu 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); } 

Você precisará criar um analisador SQL completo para isso. Eu recomendo que você use a ferramenta de linha de comando mysql para isso, invocando externamente do PHP.

Eu nunca tive que usá-lo, mas a class mysqli tem um método multi_query:

http://php.net/manual/en/mysqli.multi-query.php

Eu sei que estou bastante atrasado para a festa, mas o PHP Mini Admin foi um salvavidas em algumas ocasiões. É basicamente um “lite” PHPMyAdmin tudo contido em um arquivo, portanto, não precisa de instalações complicadas, basta carregá-lo e logar. Simples!

Não se esqueça do phpMyAdmin . Interface bastante sólida para interagir com o MySQL.

Não sei se resolve o seu problema, já que não sei se você pode interagir com ele diretamente do código, mas queria apenas jogá-lo lá.

Criei um script de migration com multi_query . Ele pode processar a saída mysqldump e as exportações phpmyadmin sem a ferramenta de linha de comando mysql. Eu também fiz alguma lógica para processar vários arquivos de migration com base no timestamp armazenado em DB como Rails. Eu sei que precisa de mais manipulação de erros, mas atualmente o trabalho para mim.

Confira: https://github.com/kepes/php-migration

Eu acho que se você não processar a input do usuário com apenas scripts feitos por desenvolvedores ou ferramentas de exportação, você pode usá-lo com segurança.

Você pode usar esse script para executar arquivos de script MySQL. Você precisará configurar $ hostName, $ userName, $ password, $ dataBaseName, $ port e $ fileName, é claro.

 < ?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'); } 

Uma sugestão:

 // connect to db. if (mysql_query("SOURCE myfile.sql")) { echo "Hello Sonny"; } 

Para executar a geração da tabela a partir do aplicativo, você pode querer criar um arquivo php que fará exatamente isso quando você executá-lo.

 $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 );