web-dev-qa-db-ja.com

PHPでMySQL * .sqlファイルを実行する

新しいWebサイトデータベースを作成するときに使用する_*.sql_ファイルが2つあります。最初のファイルはすべてのテーブルを作成します。 2番目のファイルには、いくつかのデフォルトレコードが入力されます。これらのファイルをPHPから実行したいと思います。 Zend_Frameworkも使用します(これが実現に役立つ場合)。

追加情報

  1. コンソールにアクセスできません
  2. アプリケーション内からサイト生成を自動化しようとしています。

[〜#〜] solution [〜#〜]

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"');
_

...私は有用な出力を得ることはありませんでしたが、 いくつかの提案 on 別のスレッド に従い、最終的にすべて動作しました。コマンドを_--option=value_形式に切り替え、_--execute="SOURCE ..."_の代わりに_<_を使用してファイルを実行しました。

また、Shell_exec()exec()の違いについての良い説明もありませんでした。

44
Sonny

この質問は時々出てきます。 PHPから.sqlスクリプトを直接実行するための適切なソリューションはありません。 .sqlスクリプトで一般的なステートメントをSQLステートメントとして実行できないEdgeのケースがあります。たとえば、mysqlツールには builtin commands がありますが、MySQLサーバーでは認識されません。 CONNECTTEESTATUS、およびDELIMITER

だから、@ Ignacio Vazquez-Abramsの answer に+1を付けます。 .sqlスクリプトをPHPで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');

これらの関連する質問に対する私の回答も参照してください。

41
Bill Karwin
$commands = file_get_contents($location);   
$this->_connection->multi_query($commands);
18
Farid Movsumov

私が使用するものは次のとおりです。


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);
}
14
Ibrahim Lawal

これには完全なSQLパーサーを作成する必要があります。代わりにmysqlコマンドラインツールを使用して、PHPから外部で呼び出すことをお勧めします。

使用する必要はありませんでしたが、mysqliクラスにはmulti_queryメソッドがあります。

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

6
Dave

私はパーティーにかなり遅れていることを知っていますが、 PHP Mini Admin は、いくつかの機会で命の恩人でした。基本的にすべてが1つのファイルに含まれる「ライト」PHPMyAdminなので、複雑なインストールは不要です。アップロードしてログインするだけです。

6
Matthew

phpMyAdmin を忘れないでください。 MySQLと対話するための非常に堅固なインターフェース。

それがあなたの問題を解決するかどうかはわかりません、なぜならあなたがコードから直接それと対話できるかどうかわからないからです。

2
jocull

multi_queryを使用して移行スクリプトを作成しました。 mysqlコマンドラインツールなしでmysqldump出力とphpmyadminエクスポートを処理できます。 RailsのようなDBに保存されているタイムスタンプに基づいて、複数の移行ファイルを処理するロジックも作成しました。私はそれがより多くのエラー処理を必要とすることを知っていますが、現在私のために仕事をしています。

チェックしてください: https://github.com/kepes/php-migration

開発者が作成したスクリプトまたはエクスポートツールのみでユーザー入力を処理しない場合、安全に使用できると思います。

1
kepes

このスクリプトを使用して、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');
}
1
Sergiy Lavryk

アプリケーション内からテーブル生成を実行するには、実行時にそれを行う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 );
0
kizito Ikapel

1つの提案:

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

  echo "Hello Sonny";

} 
0
zerodin

これが私の解決策であり、以下のコードが何をするかを説明しています。原則は、ファイルを1行ずつ読み取り、クエリを作成して、それぞれを実行することです。 「file_get_contents」を使用する多くのソリューションを見ましたが、これはファイル全体を文字列変数に読み込む際にバッファの問題を引き起こす可能性があるため、良いソリューションではありません。私のソリューションでは、TRIGGERのクエリも考慮しています。配列の割り当てはありません。コメントと空の行は削除されます。

<?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;

}

0
N'faly Kaba