在PHP中运行MySQL*.sql文件

在PHP中运行MySQL*.sql文件,php,mysql,zend-framework,scripting,Php,Mysql,Zend Framework,Scripting,我有两个*.sql文件,我在创建新网站数据库时使用它们。第一个文件创建所有表。第二个文件填充一些默认记录。我想从PHP执行这些文件。我还使用Zend_框架,如果这有助于实现这一点的话 其他信息 我没有控制台访问权限 我正在尝试从应用程序中自动生成站点 解决方案 使用shell\u exec() $command = 'mysql' . ' --host=' . $vals['db_host'] . ' --user=' . $vals['db_user']

我有两个
*.sql
文件,我在创建新网站数据库时使用它们。第一个文件创建所有表。第二个文件填充一些默认记录。我想从PHP执行这些文件。我还使用Zend_框架,如果这有助于实现这一点的话

其他信息

  • 我没有控制台访问权限
  • 我正在尝试从应用程序中自动生成站点
  • 解决方案

    使用
    shell\u 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…”
    而不是
    ,您需要为此创建一个完整的SQL解析器。我建议您使用
    mysql
    命令行工具,从PHP外部调用它。

    一个建议:

    // connect to db.
    if (mysql_query("SOURCE myfile.sql")) {
    
      echo "Hello Sonny";
    
    } 
    
    别忘了。与MySQL交互的非常可靠的界面


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

    这个问题不时出现。直接从PHP运行.sql脚本没有好的解决方案。有些情况下,.sql脚本中常见的语句不能作为sql语句执行。例如,mysql工具具有mysql服务器无法识别的属性,例如,
    CONNECT
    TEE
    状态
    ,以及
    分隔符

    所以我给@Ignacio Vazquez Abrams的+1。您应该通过调用
    mysql
    工具在PHP中运行.sql脚本,例如使用


    我做了这个测试:

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

    另请参见我对这些相关问题的回答:

      • 以下是我使用的:



        我从未使用过它,但mysqli类有一个multi_查询方法:


        我知道我参加晚会已经很晚了,但有好几次我都是救命恩人。它基本上是一个“lite”PHPMyAdmin,全部包含在一个文件中,因此不需要复杂的安装,只需上传并登录即可。傻瓜

        我用
        multi\u query
        创建了一个迁移脚本。它可以处理mysqldump输出和phpmyadmin导出,而无需mysql命令行工具。我还制定了一些逻辑,根据存储在DB-like Rails中的时间戳来处理多个迁移文件。我知道它需要更多的错误处理,但目前为我做的工作

        请查看:


        我认为,如果您不使用它处理用户输入,只有开发人员编写的脚本或导出工具,您才能安全地使用它。

        要在应用程序中执行表生成,您可能需要创建一个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 );
        

        您可以使用此脚本运行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');
        }
        

        这是我的解决方案,下面的代码解释了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;
        

        只想添加到上面给出的@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 />
        

        执行命令的控制器代码

        $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;
        }
        
        $con=新连接();
        $mysqli=new mysqli($con->get_databaseURL(),$con->get_databaseUName(),$con->get_databasePWord(),$con->get_databaseName())或die('无法连接到数据库服务器'。mysqli_connect_error());
        如果(isset($\u 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);
        如果(!空($output))
        echo“执行SQL脚本
        ”; 其他的 echo“无法执行SQL脚本
        ”; 返回; }
        您不能使用控制台吗?这就简单多了……@Pekka-更新了我的帖子,这对我在linux上的表现非常好。还没有在windows xampp上尝试过,但它怀疑它是否能工作:)与
        shell\u exec()
        之间的区别在于
        shell\u exec
        以字符串形式返回所有输出流
        exec
        返回输出的最后一行。via Here是我提出的一个非常好的解决方案,如果它能起作用(取决于特权),它肯定是最好的方法。不,
        SOURCE
        是mysql工具的内置工具。您不能将其作为SQL查询执行。
        mysql\u query()
        不支持多个查询。有多种方法可以解决此问题。但是,请注意这些疑问;如果不小心,则很容易发生sql注入。读一读:还有一个很好的建议。在纯PHP中解析mySQL转储非常糟糕,phpMyAdmin减轻了它的痛苦(虽然不是自动的)。我正在尝试shell_exec()路由,但没有找到指定要执行的文件的示例。这就是我目前所拥有的:
        shell_exec('mysql'.-u'.$vals['db_user'.].-p'.$vals['db_pass'.].-D'.$vals['db_name'])
        您读取要使用shell重定向执行的文件:
        mysql…
        我想我会对
          <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 />
        
          $('#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;
        }