programing

PHP에서 MySQL *.sql 파일 실행

minecode 2022. 12. 10. 11:08
반응형

PHP에서 MySQL *.sql 파일 실행

난 두 개가 있다.*.sql새 웹 사이트 데이터베이스를 작성할 때 사용하는 파일입니다.첫 번째 파일이 모든 테이블을 만듭니다.두 번째 파일은 몇 가지 기본 레코드를 채웁니다.이 파일들을 PHP에서 실행하고 싶습니다.Zend_Framework도 사용합니다.

추가 정보

  1. 콘솔에 액세스할 수 없습니다.
  2. 애플리케이션 내에서 사이트 생성을 자동화하려고 합니다.

솔루션

사용.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().

이 질문은 가끔 나온다.PHP에서 직접 .sql 스크립트를 실행하는 데 적합한 솔루션은 없습니다..sql 스크립트에서 일반적인 문을 SQL 문으로 실행할 수 없는 경우가 있습니다.예를 들어 mysql 툴에는 MySQL Server에서 인식하지 못하는 명령어가 포함되어 있습니다.CONNECT,TEE,STATUS,그리고.DELIMITER.

그래서 나는 @Ignacio Vazquez-Abrams의 대답에 +1을 주었다.PHP에서 .sql 스크립트를 실행하려면mysql도구(예: )를 사용합니다.


이 테스트는 성공했습니다.

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

다음 관련 질문에 대한 답변도 참조하십시오.

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

이를 위해 전체 SQL 파서를 생성해야 합니다.를 사용하는 것을 추천합니다.mysql대신 이를 위한 명령줄 도구를 사용하여 PHP에서 외부에서 호출합니다.

사용하고 있는 것은 다음과 같습니다.


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

사용할 필요는 없지만 mysqli 클래스는 multi_query 메서드를 사용합니다.

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

파티에 늦은 건 알지만 PHP Mini Admin은 몇 번인가 생명의 은인이 되었습니다.기본적으로는 1개의 파일에 모두 포함된 "lite" PHPMyAdmin이므로 복잡한 설치는 필요 없습니다.업로드 후 로그인만 하면 됩니다.시뮬레이션!

phpMyAdmin도 잊지 마세요.MySQL과 대화하기 위한 매우 견고한 인터페이스입니다.

코드에서 직접 대화할 수 있을지는 모르겠지만 그냥 버리고 싶었어요

이 스크립트를 사용하여 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');
}

했습니다.multi_query toolmysql 명령어라인 tool.mysql 명령어라인 tool.mysql 명령어라인 phmyadmin 출력 및 할 수 또한 Rails와 같이 DB에 저장된 타임스탬프를 기반으로 여러 마이그레이션 파일을 처리하는 논리를 만들었습니다.에러처리가 더 필요한 것은 알지만, 현재 저를 위해 작업을 하고 있습니다.

https://github.com/kepes/php-migration에서 확인하세요.

개발자가 만든 스크립트나 내보내기 도구만 가지고 사용자 입력을 처리하지 않으면 안전하게 사용할 수 있다고 생각합니다.

다음은 저의 솔루션이며, 아래 코드는 이 기능을 설명합니다.원칙은 파일을 한 줄씩 읽고 쿼리를 작성하고 각각의 파일을 실행하는 것입니다."file_get_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;

}

응용 프로그램 내에서 테이블 생성을 실행하려면 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 );

위의 @Bill Karwin 답변에 추가하고 싶습니다.

버튼을 클릭하기만 하면 SQL 스크립트파일을 사용하여 데이터베이스를 Import/재초기화/실행할 수 있습니다.이 버튼은 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 />

아약스를 호출하는 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;
}

한 가지 제안:

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

  echo "Hello Sonny";

} 

언급URL : https://stackoverflow.com/questions/4027769/running-mysql-sql-files-in-php

반응형