web-dev-qa-db-ja.com

mysqlをmysqliに変更する方法は?

私は通常のmysqlに使用する以下のこのコードに基づいて、mysqliを使用するようにどのように変換できますか?

**​​ mysql _query($ sql);を変更するのと同じくらい簡単ですか? to mysqli _query($ sql); **

<?PHP

//in my header file that is included on every page I have this
$DB["dbName"] = "emails";
$DB["Host"] = "localhost";
$DB["user"] = "root";
$DB["pass"] = "";
$link = mysql_connect($DB['Host'], $DB['user'], $DB['pass']) or die("<center>An Internal Error has Occured. Please report following error to the webmaster.<br><br>".mysql_error()."'</center>");
mysql_select_db($DB['dbName']);
// end header connection part

// function from a functions file that I run a mysql query through in any page.
function executeQuery($sql) {
    $result = mysql_query($sql);
    if (mysql_error()) {
        $error = '<BR><center><font size="+1" face="arial" color="red">An Internal Error has Occured.<BR> The error has been recorded for review</font></center><br>';
        if ($_SESSION['auto_id'] == 1) {
            $sql_formatted = highlight_string(stripslashes($sql), true);
            $error .= '<b>The MySQL Syntax Used</b><br>' . $sql_formatted . '<br><br><b>The MySQL Error Returned</b><br>' . mysql_error();
        }
        die($error);
    }
    return $result;
}

// example query ran on anypage of the site using executeQuery function
$sql='SELECT auto_id FROM friend_reg_user WHERE auto_id=' .$info['auto_id'];
$result_member=executequery($sql);
if($line_member=mysql_fetch_array($result_member)){
    extract($line_member);
} else {
    header("location: index.php");
    exit;
}
?>
49
JasonDavis

少なくとも最初にすべきことは、少なくとも手続き型APIを使用する場合は、すべてのmysql_*関数呼び出しを同等のmysqli_*に置き換えることです。 MySQL APIに基づいたコードがあります。これは手続き型です。

これを支援するために、 MySQLi拡張機能の概要 は間違いなく役立つことが明らかになりました。

例えば:

注:一部の機能については、パラメーターを慎重に確認する必要がある場合があります:多分あちこちに違いがありますが、それほど多くはありません。同じライブラリ上(libmysql;少なくともPHP <= 5.2)

例えば:

  • mysqlでは、クエリを実行するデータベースを示すために、一度接続したら mysql_select_db を使用する必要があります
  • 一方、mysqliでは、そのデータベース名を mysqli_connect の4番目のパラメーターとして指定できます。
  • それでも、必要に応じて使用できる mysqli_select_db 関数もあります。


それが完了したら、スクリプトの新しいバージョンを実行してみてください...そして、すべてが機能するかどうかを確認してください。そうでない場合...バグハンティングの時間;-)

70
Pascal MARTIN

(私はこれが古いことを理解していますが、それでもまだ現れます...)

mysql_*mysqli_*に置き換えた場合、mysqli_*関数のロード全体がデータベースリンクを渡す必要があることに注意してください。

例えば。:

mysql_query($query)

になる

mysqli_query($link, $query)

つまり、多くのチェックが必要です。

31
dhw

私がいつもこれを処理する最も簡単な方法

 $con = mysqli_connect($serverName,$dbusername,$dbpassword);

次の順序での3ステップの交換

  1. すべての "mysql_select_db(" with "mysqli_select_db($ con、"
  2. すべての "mysql_query(" with "mysqli_query($ con、"および
  3. すべての「mysql _」と「mysqli _」。

これはいつも私のために働く

14

SQLアクセスに [〜#〜] pdo [〜#〜] を使用することをお勧めします。

次に、ドライバーを変更し、新しいバックエンドでSQLが機能することを確認するだけです。理論的には。データの移行は別の問題です。

抽象データベースアクセスは素晴らしいです。

6
Aiden Bell

大きなプロジェクトの場合、多くのファイルを変更する必要があります。また、PHPの以前のプロジェクトバージョンが5.6で、新しいバージョンが7.1の場合、新しいファイルsql.phpを作成して含めることができますヘッダーまたはどこかで常に使用しており、SQL接続が必要です。例:

//local
$sql_Host =     "localhost";      
$sql_username = "root";    
$sql_password = "";       
$sql_database = "db"; 


$mysqli = new mysqli($sql_Host , $sql_username , $sql_password , $sql_database );

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

// /* change character set to utf8 */
if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
    exit();
} else {
    // printf("Current character set: %s\n", $mysqli->character_set_name());
}
if (!function_exists('mysql_real_escape_string')) {
    function mysql_real_escape_string($string){
        global $mysqli;
        if($string){
            // $mysqli = new mysqli($sql_Host , $sql_username , $sql_password , $sql_database );            
            $newString =  $mysqli->real_escape_string($string);
            return $newString;
        }
    }
}
// $mysqli->close();
$conn = null;
if (!function_exists('mysql_query')) {
    function mysql_query($query) {
        global $mysqli;
        // echo "DAAAAA";
        if($query) {
            $result = $mysqli->query($query);
            return $result;
        }
    }
}
else {
    $conn=mysql_connect($sql_Host,$sql_username, $sql_password);
    mysql_set_charset("utf8", $conn);
    mysql_select_db($sql_database);
}

if (!function_exists('mysql_fetch_array')) {
    function mysql_fetch_array($result){
        if($result){
            $row =  $result->fetch_assoc();
            return $row;
        }
    }
}

if (!function_exists('mysql_num_rows')) {
    function mysql_num_rows($result){
        if($result){
            $row_cnt = $result->num_rows;;
            return $row_cnt;
        }
    }
}

if (!function_exists('mysql_free_result')) {
    function mysql_free_result($result){
        if($result){
            global $mysqli;
            $result->free();

        }
    }
}

if (!function_exists('mysql_data_seek')) {
    function mysql_data_seek($result, $offset){
        if($result){
            global $mysqli;
            return $result->data_seek($offset);

        }
    }
}

if (!function_exists('mysql_close')) {
    function mysql_close(){
        global $mysqli;
        return $mysqli->close();
    }
}

if (!function_exists('mysql_insert_id')) {
    function mysql_insert_id(){
            global $mysqli;
            $lastInsertId = $mysqli->insert_id;
            return $lastInsertId;
    }
}

if (!function_exists('mysql_error')) {
    function mysql_error(){
        global $mysqli;
        $error = $mysqli->error;
        return $error;
    }
}
4
Svetoslav

_mysql_*_関数をMySQLi APIにアップグレードするための究極のガイド

新しいmysqli拡張の理由は、MySQLシステムバージョン4.1.3以降にある新しい機能を利用するためです。既存のコードを_mysql_*_からmysqli APIに変更する場合、これらの改善を利用する必要があります。そうしないと、アップグレードの努力が無駄になります。
mysqli拡張には多くの利点があり、mysql拡張に対する主要な機能強化は次のとおりです。

  • オブジェクト指向インターフェース
  • 準備済みステートメントのサポート
  • 強化されたデバッグ機能

_mysql_*_関数からMySQLiにアップグレードする場合、これらの機能と、このAPIの使用方法のいくつかの変更を考慮することが重要です。

1.オブジェクト指向インターフェースと手続き型関数。

新しいmysqliオブジェクト指向インターフェイスは、古い関数よりも大幅に改善されており、コードをよりクリーンにし、誤植の影響を受けにくくすることができます。このAPIの手続き型もありますが、コードの可読性が低下し、エラーが発生しやすくなるため、このAPIの使用は推奨されません。

MySQLiを使用してデータベースへの新しい接続を開くには、MySQLiクラスの新しいインスタンスを作成する必要があります。

_$mysqli = new \mysqli($Host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
_

手続き型スタイルを使用すると、次のようになります。

_$mysqli = mysqli_connect($Host, $user, $password, $dbName);
mysqli_set_charset($mysqli, 'utf8mb4');
_

最初の3つのパラメーターのみが_mysql_connect_と同じであることに注意してください。古いAPIの同じコードは次のようになります。

_$link = mysql_connect($Host, $user, $password);
mysql_select_db($dbName, $link);
mysql_query('SET NAMES utf8');
_

PHPコードがphp.iniで定義されたデフォルトのパラメーターを使用した暗黙的な接続に依存している場合、コードでパラメーターを渡すMySQLi接続を開き、すべての手続き関数への接続リンクを提供するか、 OOPスタイル。

詳細については、記事を参照してください: mysqliを使用して適切に接続する方法

2.準備済みステートメントのサポート

これは大きなものです。 MySQLは、MySQL 4.1(2004)でネイティブ準備済みステートメントのサポートを追加しました。準備済みステートメントは、 SQLインジェクションを防ぐ に最適な方法です。ネイティブのプリペアドステートメントのサポートがPHPに追加されたのは論理的でした。 SQLステートメントとともにデータを渡す必要がある場合は常に、準備済みステートメントを使用する必要があります(つまり、WHEREINSERT、またはUPDATEが通常の使用例です)。

古いMySQL APIには _mysql_real_escape_string_ と呼ばれるSQLで使用される文字列をエスケープする機能がありましたが、 SQLインジェクションに対する保護を意図したものではありませんでした 目的のために使用されます。
新しいMySQLi APIは、後方互換性のための代替関数 _mysqli_real_escape_string_ を提供します。これは、古いものと同じ問題に悩まされるため、準備済みステートメントが使用されない限り使用しないでください。利用できます。

古いmysql_ *の方法:

_$login = mysql_real_escape_string($_POST['login']);
$result = mysql_query("SELECT * FROM users WHERE user='$login'");
_

準備されたステートメントの方法:

_$stmt = $mysqli->prepare('SELECT * FROM users WHERE user=?');
$stmt->bind_param('s', $_POST['login']);
$stmt->execute();
$result = $stmt->get_result();
_

MySQLi の準備されたステートメントは、初心者には少し不快に見えるかもしれません。新しいプロジェクトを開始する場合は、より強力でシンプルな [〜#〜] pdo [〜#〜] APIを使用することをお勧めします。

3.強化されたデバッグ機能

一部の旧式のPHP開発者は、SQLエラーを手動で確認し、デバッグの手段としてブラウザに直接表示することに慣れています。ただし、このような方法は面倒なだけでなく、セキュリティリスクでもあることが判明しました。ありがたいことに、MySQLiはエラー報告機能を改善しました。

MySQLiは、発生したエラーをPHP例外として報告できます。 PHP例外はスクリプト内で発生し、未処理の場合は即座に終了します。つまり、エラーのあるステートメントの後のステートメントは実行されません。例外はPHP致命的エラーをトリガーし、PHPコアから_display_errors_および_log_errors_設定に従ってトリガーされたエラーとして動作します。 MySQLi例外を有効にするには、mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)行を使用して、DB接続を開く直前に挿入します。

_mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($Host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
_

次のようなコードの作成に慣れている場合:

_$result = mysql_query('SELECT * WHERE 1=1');
if (!$result) {
    die('Invalid query: ' . mysql_error());
}
_

または

_$result = mysql_query('SELECT * WHERE 1=1') or die(mysql_error());
_

コードでdie()する必要がなくなりました。

_mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($Host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');

$result = $mysqli->query('SELECT * FROM non_existent_table');
// The following line will never be executed due to the mysqli_sql_exception being thrown above
foreach ($result as $row) {
    // ...
}
_

何らかの理由で例外を使用できない場合、MySQLiにはエラー取得のための同等の機能があります。 mysqli_connect_error()を使用して接続エラーをチェックし、mysqli_error($mysqli)を使用して他のエラーをチェックできます。 mysqli_error($mysqli)の必須引数に注意するか、またはOOPスタイルに固執して_$mysqli->error_を使用します。

_$result = $mysqli->query('SELECT * FROM non_existent_table') or trigger_error($mysqli->error, E_USER_ERROR);
_

詳細については、これらの投稿を参照してください。
mysqliまたはdie、死ななければなりませんか?
異なる環境でMySQLiエラー情報を取得する方法?

4.その他の変更

残念ながら、_mysql_*_のすべての関数が、名前と接続リンクに最初のパラメーターとして「i」を追加しただけでMySQLiに対応するものがあるわけではありません。それらのいくつかのリストはここにあります:

  • mysql_client_encoding()mysqli_character_set_name($mysqli)に置き換えられました
  • _mysql_create_db_には対応するものがありません。代わりに準備済みステートメントまたは_mysqli_query_を使用してください
  • _mysql_drop_db_には対応するものがありません。代わりに準備済みステートメントまたは_mysqli_query_を使用してください
  • _mysql_db_name_&_mysql_list_dbs_サポートは、SQLの_SHOW DATABASES_を支持して削除されました。
  • _mysql_list_tables_サポートは、SQLの_SHOW TABLES FROM dbname_を支持して削除されました。
  • _mysql_list_fields_サポートは、SQLの_SHOW COLUMNS FROM sometable_を支持して削除されました。
  • _mysql_db_query_-> mysqli_select_db()を使用してからクエリを実行するか、クエリでDB名を指定します
  • mysql_fetch_field($result, 5)-> 2番目のパラメーター(オフセット)は_mysqli_fetch_field_に存在しません。返されるさまざまな結果を念頭に置いて_mysqli_fetch_field_direct_を使用できます
  • _mysql_field_flags_、_mysql_field_len_、_mysql_field_name_、_mysql_field_table_&_mysql_field_type_->は_mysqli_fetch_field_direct_に置き換えられました
  • _mysql_list_processes_は削除されました。スレッドIDが必要な場合は、_mysqli_thread_id_を使用します
  • _mysql_pconnect_は、mysqli_connect()で置き換えられ、_p:_ホストプレフィックスが付きます
  • _mysql_result_-> mysqli_data_seek()およびmysqli_field_seek()と組み合わせてmysqli_fetch_field()を使用
  • _mysql_tablename_サポートは、SQLの_SHOW TABLES_を支持して削除されました。
  • _mysql_unbuffered_query_は削除されました。詳細については、この記事を参照してください バッファ付きクエリとバッファなしクエリ
2
Dharman

プロジェクトで変更するファイルがたくさんある場合は、mysql関数のような同じ名前の関数を作成し、関数内で次のコードのように変換します。

$sql_Host =     "your Host";      
$sql_username = "username";    
$sql_password = "password";       
$sql_database = "database";       



$mysqli = new mysqli($sql_Host , $sql_username , $sql_password , $sql_database );


/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}


function mysql_query($query){
    $result = $mysqli->query($query);
    return $result;

}

function mysql_fetch_array($result){
    if($result){
        $row =  $result->fetch_assoc();
         return $row;
       }
}

function mysql_num_rows($result){
    if($result){
         $row_cnt = $result->num_rows;;
         return $row_cnt;
       }
}
1
Esty Shlomovitz

PHP upgrade。から顧客のホスティングを5.4(OMG !!!)にアップグレードした後に使用しました。 7.x PHPバージョン。

これは回避策であり、PDOまたはmysqliクラスを使用してすべてのコードを書き換えることをお勧めします。

1.接続定義

まず、新しい変数_$link_または_$con_、または必要なものに接続する必要があります。

接続を次から変更します。

_@mysql_connect($Host, $username, $password) or die("Error message...");
@mysql_select_db($db);
_

または

_@mysql_connect($Host, $username, $password, $db) or die("Error message...");
_

に:

_$con = mysqli_connect($Host, $username, $password, $db) or die("Error message...");
_

2. mysql_ *の変更

Notepad ++では、「ファイルを検索」(Ctrl + Shift + f)を使用します。

Search and replace notepad++ box

次の順序で「ファイルに置き換える」を選択します。

  1. mysql_query(-> mysqli_query($ con、

  2. mysql_error()-> mysqli_error($ con)

  3. mysql_close()-> mysqli_close($ con)

  4. mysql_-> mysqli_

3.調整

エラーが発生した場合、関数から$ conにアクセスできないことが原因である可能性があります。

すべての関数に_global $con;_を追加する必要があります。例:

_function my_function(...) {
    global $con;
    ...
}
_

SQLクラスでは、_$this->con_の代わりに_$con_に接続します。各関数呼び出しで置き換えます(例:mysqli_query($con, $query);

それが役に立てば幸い。

0
Meloman