在php中运行mysql*.sql文件

nzk0hqpo  于 2021-06-24  发布在  Mysql
关注(0)|答案(13)|浏览(396)

我有两个 *.sql 创建新网站数据库时使用的文件。第一个文件创建所有表。第二个文件填充一些默认记录。我想从php执行这些文件。我还使用zendèu框架,如果这有助于实现这一点的话。
附加信息
我没有控制台访问权限
我正在尝试从我们的应用程序中自动生成站点。
解决方案
使用 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"');

…我从来没有得到有用的输出,但在另一个线程上遵循了一些建议,最终使它全部工作。我切换到 --option=value 命令的格式和使用的 --execute="SOURCE ..." 而不是 < 执行文件。
而且,我从来没有得到一个很好的解释之间的区别 shell_exec() 以及 exec() .

unguejic

unguejic1#

要在应用程序中执行表生成,您可能需要创建一个php文件,当您运行它时,它将执行此操作。

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

5anewei62#

我从未使用过它,但mysqli类有一个multi\u查询方法:
http://php.net/manual/en/mysqli.multi-query.php

4nkexdtk

4nkexdtk3#

我创建了一个迁移脚本 multi_query . 它可以在不使用mysql命令行工具的情况下处理mysqldump输出和phpmyadmin导出。我还做了一些逻辑来处理基于存储在db-like-rails中的时间戳的多个迁移文件。我知道它需要更多的错误处理,但目前为我做的工作。
过来看:https://github.com/kepes/php-migration
我认为如果你不处理用户输入,只处理由开发人员或导出工具生成的脚本,你就可以安全地使用它。

nbnkbykc

nbnkbykc4#

一个建议:

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

  echo "Hello Sonny";

}
wpx232ag

wpx232ag5#

$commands = file_get_contents($location);   
$this->_connection->multi_query($commands);
n1bvdmb6

n1bvdmb66#

我知道我参加派对已经很晚了,但php mini admin在很多场合都是救星。它基本上是一个“lite”phpmyadmin,全部包含在一个文件中,因此不需要复杂的安装,只需上传并登录即可。傻瓜!

vktxenjb

vktxenjb7#

只是想补充一下上面给出的@bill karwin答案。
可以导入|重新初始化|执行自定义sql;数据库使用sql脚本文件,只需点击按钮。该按钮将使用ajax执行sql脚本文件。
如。
前端代码

<input type="button" value="Execute SQL Script" id="btnExecuteScript" />
  <input type="button" value="reset" onclick="clearDiv('divExecuteScript')" />
  <div id="divExecuteScript" style='display: none'></div>
  <br />

调用ajax的jquery代码

$('#btnExecuteScript').click(function (event) {
    if ($('#divExecuteScript').html() == '') {
      $('#divExecuteScript').html("<b style='font-family: sans-serif;font-size: larger'>Please Wait, It might take a few minutes</b>");
      $('#divExecuteScript').show();
      $.get("../controller/Controller.php?executeScript=TRUE", function (data) {
        // alert("$" + data + "$");
        $('body').css('cursor', 'default');
        $('#divExecuteScript').html(data);
        $('#divExecuteScript').show();
      });
    } else
      $('#divExecuteScript').toggle();
  });

连接文件

class Conn {

    protected $databaseURL; // const
    protected $databaseName;
    protected $databaseUName;
    protected $databasePWord;
    public $mysqli;

        public function __construct($args = null) {
        if (stripos($_SERVER['SERVER_NAME'], "localhost") !== FALSE) {
                $this->databaseURL = "host"; 
                $this->databaseName = "database";
                $this->databaseUName = "user";
                $this->databasePWord = "password";
            } 
            $this->mysqli = new mysqli($this->databaseURL, $this->databaseUName, $this->databasePWord, $this->databaseName) or die('Could not connect to the database server' . mysqli_connect_error());

             if (empty($this->mysqli))
               die("Error while connecting to host"); 
    }

    function get_databaseURL() {
        return $this->databaseURL;
    }

    function get_databaseUName() {
        return $this->databaseUName;
    }

    function get_databasePWord() {
        return $this->databasePWord;
    }

    function get_databaseName() {
        return $this->databaseName;
    }

}

执行命令的控制器代码

$con = new Conn();
  $mysqli = new mysqli($con->get_databaseURL(), $con->get_databaseUName(), $con->get_databasePWord(), $con->get_databaseName()) or die('Could not connect to the database server' . mysqli_connect_error());

if (isset($_GET['executeScript'])) {
  $script_path = '/path-to-script-file/filename.sql';
  $command = "mysql --user={$con->get_databaseUName()} --password='{$con->get_databasePWord()}' "
  . "-h {$con->get_databaseURL()} -D {$con->get_databaseName()} < {$script_path}";
  $output = shell_exec($command);

  if (!empty($output))
    echo "<b style='font-family: sans-serif;font-size: large'>Execute the SQL script<br />";
  else
    echo "<b style='font-family: sans-serif;font-size: large'>Unable to execute the SQL script</b><br />";

  return;
}
oiopk7p5

oiopk7p58#

别忘了phpmyadmin。与mysql交互的非常可靠的接口。
我不知道它是否解决了您的问题,因为我不知道您是否可以直接从代码与它交互,但我只是想把它扔出去。

nbnkbykc

nbnkbykc9#

您需要为此创建一个完整的sql解析器。我建议你使用 mysql 命令行工具,从php外部调用它。

xam8gpfp

xam8gpfp10#

可以使用此脚本运行mysql脚本文件。当然,您需要设置$hostname、$username、$password、$databasename、$port和$filename。

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

f1tvaqid11#

这个问题时有发生。直接从php运行.sql脚本没有好的解决方案。有些边缘情况下,.sql脚本中常见的语句不能作为sql语句执行。例如,mysql工具具有mysql服务器无法识别的内置命令,例如。 CONNECT , TEE , STATUS ,和 DELIMITER .
所以我给@ignacio vazquez abrams的答案加1。您应该通过调用 mysql 工具,例如 shell_exec() .
我做了个测试:

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

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

另请参见我对这些相关问题的回答:
从php中加载.sql文件
是否可以从另一个sql脚本中的存储过程调用sql脚本?
php:一条mysql\u查询语句中的多个sql查询

ig9co6j1

ig9co6j112#

我用的是:

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);
}
d7v8vwbk

d7v8vwbk13#

下面是我的解决方案,下面的代码解释了is的作用。其原理是逐行读取文件,构建查询并执行每个查询。我看到许多解决方案使用“file\u get\u contents”,这不是一个好的解决方案,因为当它将整个文件内容读取到字符串变量时,可能会导致缓冲区问题。我的解决方案还考虑了触发器的查询。没有数组分配,注解和空行被剥离。

<?php
 /**
 * Get a connection from database
 * @param type $db_host database hostname
 * @param type $db_user database username
 * @param type $db_password database password
 * @param type $db_name database name
 * @return \PDO
 */
 function get_db_connection($db_host, $db_user, $db_password, $db_name)
{
    $dns = "mysql:host=$db_host;dbname=$db_name";
    try
    {
        return new PDO($dns, $db_user, $db_password);
    } catch (PDOException $ex)
    {
        return null;
    }
}

/**
 * Runs SQL queries from file
 */

 function exec_sql_queries_from_file($script_file, $db_host, $db_user, $db_password, $db_name)
{
    // to increase the default PHP execution time
    set_time_limit ( 60 ); // Max time = 60 seconds

    // Connect to database
    $connection = get_db_connection($db_host, $db_user, $db_password, $db_name);

    // If the connection is acquired
    if($connection != null){

        // Open sql file
        $f = fopen($script_file, 'r');

        // sql query
        $query = '';

        // Default delimiter for queries
        $delimiter = ';';

        // read line by line
        while (!feof($f))
        {           
            $line = str_replace(PHP_EOL, '', fgets($f)); // read a line and remove the end of line character

            /* if the current line contains the key word 'DELIMITER'. Ex: DELIMITER ;; or DELIMITER $$
             * mostly used for TRIGGERS' queries
             */
            if(strpos($line, 'DELIMITER') !== false)
            {
                // change the delimiter and read the next line
                $delimiter = str_replace('DELIMITER ', '', $line);
                continue;
            }   

            // Consider the line as part of a query if it's not empty and it's not a comment line
            if (!empty($line) && !starts_with($line, '/*') && !starts_with($line, '--'))
            {
                // the query hasn't reach its end: concatenate $line to $query if $line is not a delimiter
                $query .= $line !== $delimiter ? $line : '';

                // if the current line ends with $delimiter: end of current query
                if (ends_with($line, $delimiter))
                {                
                    // exec the query
                    $connection->exec($query) or die($connection->errorInfo());
                    // start new query
                    $query = '';
                }
            }                    
        }

        fclose($f);
    }
}

 /**
 * Starts with function
 */
function starts_with($haystack, $needle)
{
    return $haystack{0} === $needle{0} ? stripos($haystack, $needle) === 0 : false;
}

/**
 * Ends with function
 */
function ends_with($haystack, $needle)
{
    $pos = stripos($haystack, $needle);
    return $pos === FALSE ? FALSE : substr($haystack, $pos) === $needle;

}

相关问题