web-dev-qa-db-fra.com

Comment changer mysql en mysqli?

Sur la base de ce code ci-dessous que j'utilise pour mysql normal, comment pourrais-je le convertir pour utiliser mysqli?

Est-ce aussi simple que de changer ** mysql _query ($ sql); à 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

La première chose à faire serait probablement de remplacer chaque mysql_* appel de fonction avec son équivalent mysqli_*, au moins si vous êtes prêt à utiliser l'API procédurale - ce qui serait le moyen le plus simple, étant donné que vous avez déjà du code basé sur l'API MySQL, qui est procédurale.

Pour aider à cela, le The MySQLi Extension Function Summary est certainement quelque chose qui s'avérera utile.

Par exemple:

Remarque: pour certaines fonctions, vous devrez peut-être vérifier attentivement les paramètres: il y a peut-être des différences ici et là - mais pas beaucoup, je dirais: mysql et mysqli sont basés sur la même bibliothèque (libmysql; au moins pour PHP <= 5.2)

Par exemple:

  • avec mysql, vous devez utiliser le mysql_select_db une fois connecté, pour indiquer sur quelle base de données vous souhaitez effectuer vos requêtes
  • mysqli, d'autre part, vous permet de spécifier ce nom de base de données comme quatrième paramètre pour mysqli_connect .
  • Pourtant, il y a aussi un mysqli_select_db fonction que vous pouvez utiliser si vous préférez.


Une fois que vous avez terminé, essayez d'exécuter la nouvelle version de votre script ... Et vérifiez si tout fonctionne; sinon ... Il est temps de chasser les insectes ;-)

70
Pascal MARTIN

(Je me rends compte que c'est vieux, mais ça revient quand même ...)

Si vous remplacez mysql_* avec mysqli_* gardez à l'esprit qu'une charge entière de mysqli_* les fonctions nécessitent que le lien de base de données soit transmis.

Par exemple.:

mysql_query($query)

devient

mysqli_query($link, $query)

C'est-à-dire, beaucoup de vérification requise.

31
dhw

La manière la plus simple que je gère toujours ce lieu

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

Remplacement en 3 étapes dans l'ordre suivant

  1. Tous "mysql_select_db (" avec "mysqli_select_db ($ con,"
  2. Tous "mysql_query (" avec "mysqli_query ($ con," et
  3. Tous "mysql _" avec "mysqli _".

Cela fonctionne pour moi à chaque fois

14

Je recommanderais provisoirement d'utiliser PDO pour votre accès SQL.

Il ne s'agit alors que de changer le pilote et de s'assurer que le SQL fonctionne sur le nouveau backend. En théorie. La migration des données est un problème différent.

L'accès à la base de données abstraite est excellent.

6
Aiden Bell

En cas de gros projets, de nombreux fichiers à modifier et aussi si la version précédente du projet PHP était 5.6 et la nouvelle est 7.1, vous pouvez créer un nouveau fichier sql.php et l'inclure dans l'en-tête ou un endroit où vous l'utilisez tout le temps et avez besoin d'une connexion SQL. Par exemple:

//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

Le guide ultime pour la mise à niveau des fonctions mysql_* Vers l'API MySQLi

La raison de la nouvelle extension mysqli était de tirer parti des nouvelles fonctionnalités des systèmes MySQL versions 4.1.3 et plus récentes. Lorsque vous changez votre code existant de mysql_* En API mysqli, vous devez bénéficier de ces améliorations, sinon vos efforts de mise à niveau pourraient être vains.
L'extension mysqli présente un certain nombre d'avantages, les principales améliorations par rapport à l'extension mysql étant:

  • Interface orientée objet
  • Prise en charge des déclarations préparées
  • Capacités de débogage améliorées

Lors de la mise à niveau des fonctions mysql_* Vers MySQLi, il est important de prendre en compte ces fonctionnalités, ainsi que certains changements dans la façon dont cette API doit être utilisée.

1. Interface orientée objet versus fonctions procédurales.

La nouvelle interface orientée objet mysqli est une grande amélioration par rapport aux anciennes fonctions et elle peut rendre votre code plus propre et moins sensible aux erreurs typographiques. Il existe également la version procédurale de cette API, mais son utilisation est déconseillée car elle conduit à un code moins lisible, ce qui est plus sujet aux erreurs.

Pour ouvrir une nouvelle connexion à la base de données avec MySQLi, vous devez créer une nouvelle instance de la classe MySQLi.

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

En utilisant un style procédural, cela ressemblerait à ceci:

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

Gardez à l'esprit que seuls les 3 premiers paramètres sont les mêmes que dans mysql_connect. Le même code dans l'ancienne API serait:

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

Si votre code PHP reposait sur une connexion implicite avec des paramètres par défaut définis dans php.ini, vous devez maintenant ouvrir la connexion MySQLi en transmettant les paramètres dans votre code, puis fournir le lien de connexion à toutes les procédures ou utilisez le style OOP.

Pour plus d'informations, consultez l'article: Comment se connecter correctement à l'aide de mysqli

2. Prise en charge des déclarations préparées

C'est un gros problème. MySQL a ajouté la prise en charge des instructions natives préparées dans MySQL 4.1 (2004). Les instructions préparées sont le meilleur moyen de empêcher l'injection SQL . Il était logique que la prise en charge des instructions natives préparées soit ajoutée à PHP. Les instructions préparées doivent être utilisées chaque fois que des données doivent être transmises avec l'instruction SQL (c'est-à-dire WHERE, INSERT ou UPDATE sont les cas d'utilisation habituels).

L'ancienne API MySQL avait une fonction pour échapper aux chaînes utilisées dans SQL appelée mysql_real_escape_string , mais elle n'a jamais été conçue pour la protection contre les injections SQL et naturellement ne devrait pas ' t être utilisé à cette fin.
La nouvelle API MySQLi offre une fonction de substitution mysqli_real_escape_string pour la compatibilité descendante, qui souffre des mêmes problèmes que l'ancienne et ne doit donc pas être utilisée à moins que les instructions préparées ne soient indisponible.

L'ancienne façon mysql_ *:

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

La manière de déclaration préparée:

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

Les instructions préparées dans MySQLi peuvent sembler un peu rebutantes pour les débutants. Si vous démarrez un nouveau projet, décider d'utiliser l'API PDO plus puissante et plus simple pourrait être une bonne idée.

3. Capacités de débogage améliorées

Certains développeurs de la vieille école PHP sont habitués à rechercher manuellement les erreurs SQL et à les afficher directement dans le navigateur comme moyen de débogage. Cependant, une telle pratique s'est avérée non seulement fastidieuse, mais aussi heureusement, MySQLi a amélioré les capacités de rapport d'erreurs.

MySQLi est en mesure de signaler toutes les erreurs qu'il rencontre sous la forme PHP exceptions. PHP exceptions bouillonneront dans le script et, si elles ne sont pas gérées, le termineront instantanément, ce qui signifie que aucune instruction après l'erreur ne sera jamais exécutée. L'exception déclenchera PHP Erreur fatale et se comportera comme toute erreur déclenchée par PHP core obéissant au display_errors Et log_errors Pour activer les exceptions MySQLi, utilisez la ligne mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) et insérez-la juste avant d'ouvrir la connexion DB.

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

Si vous aviez l'habitude d'écrire du code tel que:

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

ou

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

vous n'avez plus besoin de die() dans votre code.

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) {
    // ...
}

Si, pour une raison quelconque, vous ne pouvez pas utiliser d'exceptions, MySQLi a des fonctions équivalentes pour la récupération des erreurs. Vous pouvez utiliser mysqli_connect_error() pour vérifier les erreurs de connexion et mysqli_error($mysqli) pour toute autre erreur. Faites attention à l'argument obligatoire dans mysqli_error($mysqli) ou bien respectez OOP style et utilisez $mysqli->error.

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

Voir ces articles pour plus d'explications:
mysqli ou mourir, faut-il mourir?
Comment obtenir les informations d'erreur MySQLi dans différents environnements?

4. Autres changements

Malheureusement, toutes les fonctions de mysql_* N'ont pas leur équivalent dans MySQLi uniquement avec un "i" ajouté dans le nom et le lien de connexion comme premier paramètre. En voici une liste:

  • mysql_client_encoding() a été remplacée par mysqli_character_set_name($mysqli)
  • mysql_create_db N'a pas d'homologue. Utilisez des instructions préparées ou mysqli_query À la place
  • mysql_drop_db N'a pas d'homologue. Utilisez des instructions préparées ou mysqli_query À la place
  • La prise en charge de mysql_db_name Et mysql_list_dbs A été supprimée au profit de SHOW DATABASES De SQL
  • La prise en charge de mysql_list_tables A été abandonnée au profit de SHOW TABLES FROM dbname De SQL
  • La prise en charge de mysql_list_fields A été abandonnée au profit de SHOW COLUMNS FROM sometable De SQL
  • mysql_db_query -> utilisez mysqli_select_db() puis la requête ou spécifiez le nom de la base de données dans la requête
  • mysql_fetch_field($result, 5) -> le deuxième paramètre (offset) n'est pas présent dans mysqli_fetch_field. Vous pouvez utiliser mysqli_fetch_field_direct En gardant à l'esprit les différents résultats renvoyés
  • mysql_field_flags, mysql_field_len, mysql_field_name, mysql_field_table & mysql_field_type -> a été remplacé par mysqli_fetch_field_direct
  • mysql_list_processes A été supprimé. Si vous avez besoin d'un ID de thread, utilisez mysqli_thread_id
  • mysql_pconnect A été remplacé par mysqli_connect() par p: Préfixe d'hôte
  • mysql_result -> utilisez mysqli_data_seek() conjointement avec mysqli_field_seek() et mysqli_fetch_field()
  • La prise en charge de mysql_tablename A été abandonnée au profit de SHOW TABLES De SQL
  • mysql_unbuffered_query A été supprimé. Voir cet article pour plus d'informations requêtes tamponnées et non tamponnées
2
Dharman

Si vous avez beaucoup de fichiers à modifier dans vos projets, vous pouvez créer des fonctions avec les mêmes noms que les fonctions mysql, et dans les fonctions faire la conversion comme ce code:

$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

Voici un tutoriel complet pour le faire rapidement si vous avez besoin de refaire worgking un site Web après la mise à niveau PHP. Je l'ai utilisé après la mise à niveau de l'hébergement pour mes clients de 5.4 (OMG !!!) vers 7.x PHP.

C'est une solution de contournement et il est préférable de réécrire tout le code en utilisant PDO ou mysqli Class.

1. Définition de la connexion

Tout d'abord, vous devez mettre la connexion dans une nouvelle variable $link Ou $con, Ou ce que vous voulez.

Exemple

Modifiez la connexion de:

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

ou

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

à:

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

2. modification mysql_ *

Avec Notepad ++ j'utilise "Rechercher dans les fichiers" (Ctrl + Shift + f):

Search and replace notepad++ box

dans l'ordre suivant Je choisis "Remplacer dans les fichiers":

  1. mysql_query (-> mysqli_query ($ con,

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

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

  4. mysql_ -> mysqli_

3. ajustements

si vous obtenez des erreurs c'est peut-être parce que votre $ con n'est pas accessible depuis vos fonctions.

Vous devez ajouter un global $con; Dans toutes vos fonctions, par exemple:

function my_function(...) {
    global $con;
    ...
}

Dans la classe SQL, vous mettrez la connexion à $this->con Au lieu de $con. et le remplacer dans chaque appel de fonctions (par exemple: mysqli_query($con, $query);)

J'espère que ça aide.

0
Meloman