How to change mysql to mysqli?

前端 未结 11 1926
余生分开走
余生分开走 2020-11-21 04:55

Based on this code below I use for regular mysql, how could I convert it to use mysqli?

Is it as simple as changing mysql_query($sql); to

相关标签:
11条回答
  • 2020-11-21 05:34

    I have just created the function with the same names to convert and overwrite to the new one php7:

    $host =     "your host";      
    $un = "username";    
    $pw = "password";       
    $db = "database"; 
    
    $MYSQLI_CONNECT = mysqli_connect($host, $un, $pw, $db);
    
    function mysql_query($q) {
        global $MYSQLI_CONNECT;
        return mysqli_query($MYSQLI_CONNECT,$q);
    }
    
    function mysql_fetch_assoc($q) {
        return mysqli_fetch_assoc($q);
    }
    
    function mysql_fetch_array($q){
        return mysqli_fetch_array($q , MYSQLI_BOTH);
    }
    
    function mysql_num_rows($q){
        return mysqli_num_rows($q);
    }
    
    function mysql_insert_id() {
        global $MYSQLI_CONNECT;
        return mysqli_insert_id($MYSQLI_CONNECT);
    }
    
    function mysql_real_escape_string($q) {
        global $MYSQLI_CONNECT;
        return mysqli_real_escape_string($MYSQLI_CONNECT,$q);
    }
    

    It works for me , I hope it will work for you all , if I mistaken , correct me.

    0 讨论(0)
  • 2020-11-21 05:36

    2020+ Answer

    I've created a tool called Rector, that handles instant upgrades. There is also mysql → mysqli set.

    It handles:

    • function renaming
    • constant renaming
    • switched arguments
    • non-1:1 function calls changes, e.g.

      $data = mysql_db_name($result, $row);
      

      mysqli_data_seek($result, $row);
      $fetch = mysql_fetch_row($result);
      $data = $fetch[0];
      

    Just use it on your code:

    composer require rector/rector --dev
    vendor/bin/rector process src --set mysql-to-mysqli
    


    I've already run it on 2 big PHP projects and it works perfectly.

    0 讨论(0)
  • 2020-11-21 05:41

    The ultimate guide to upgrading mysql_* functions to MySQLi API

    The reason for the new mysqli extension was to take advantage of new features found in MySQL systems versions 4.1.3 and newer. When changing your existing code from mysql_* to mysqli API you should avail of these improvements, otherwise your upgrade efforts could go in vain.
    The mysqli extension has a number of benefits, the key enhancements over the mysql extension being:

    • Object-oriented interface
    • Support for Prepared Statements
    • Enhanced debugging capabilities

    When upgrading from mysql_* functions to MySQLi, it is important to take these features into consideration, as well as some changes in the way this API should be used.

    1. Object-oriented interface versus procedural functions.

    The new mysqli object-oriented interface is a big improvement over the older functions and it can make your code cleaner and less susceptible to typographical errors. There is also the procedural version of this API, but its use is discouraged as it leads to less readable code, which is more prone to errors.

    To open new connection to the database with MySQLi you need to create new instance of MySQLi class.

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

    Using procedural style it would look like this:

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

    Keep in mind that only the first 3 parameters are the same as in mysql_connect. The same code in the old API would be:

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

    If your PHP code relied on implicit connection with default parameters defined in php.ini, you now have to open the MySQLi connection passing the parameters in your code, and then provide the connection link to all procedural functions or use the OOP style.

    For more information see the article: How to connect properly using mysqli

    2. Support for Prepared Statements

    This is a big one. MySQL has added support for native prepared statements in MySQL 4.1 (2004). Prepared statements are the best way to prevent SQL injection. It was only logical that support for native prepared statements was added to PHP. Prepared statements should be used whenever data needs to be passed along with the SQL statement (i.e. WHERE, INSERT or UPDATE are the usual use cases).

    The old MySQL API had a function to escape the strings used in SQL called mysql_real_escape_string, but it was never intended for protection against SQL injections and naturally shouldn't be used for the purpose.
    The new MySQLi API offers a substitute function mysqli_real_escape_string for backwards compatibility, which suffers from the same problems as the old one and therefore should not be used unless prepared statements are not available.

    The old mysql_* way:

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

    The prepared statement way:

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

    Prepared statements in MySQLi can look a little off-putting to beginners. If you are starting a new project then deciding to use the more powerful and simpler PDO API might be a good idea.

    3. Enhanced debugging capabilities

    Some old-school PHP developers are used to checking for SQL errors manually and displaying them directly in the browser as means of debugging. However, such practice turned out to be not only cumbersome, but also a security risk. Thankfully MySQLi has improved error reporting capabilities.

    MySQLi is able to report any errors it encounters as PHP exceptions. PHP exceptions will bubble up in the script and if unhandled will terminate it instantly, which means that no statement after the erroneous one will ever be executed. The exception will trigger PHP Fatal error and will behave as any error triggered from PHP core obeying the display_errors and log_errors settings. To enable MySQLi exceptions use the line mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) and insert it right before you open the DB connection.

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

    If you were used to writing code such as:

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

    or

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

    you no longer need to die() in your 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) {
        // ...
    }
    

    If for some reason you can't use exceptions, MySQLi has equivalent functions for error retrieval. You can use mysqli_connect_error() to check for connection errors and mysqli_error($mysqli) for any other errors. Pay attention to the mandatory argument in mysqli_error($mysqli) or alternatively stick to OOP style and use $mysqli->error.

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

    See these posts for more explanation:
    mysqli or die, does it have to die?
    How to get MySQLi error information in different environments?

    4. Other changes

    Unfortunately not every function from mysql_* has its counterpart in MySQLi only with an "i" added in the name and connection link as first parameter. Here is a list of some of them:

    • mysql_client_encoding() has been replaced by mysqli_character_set_name($mysqli)
    • mysql_create_db has no counterpart. Use prepared statements or mysqli_query instead
    • mysql_drop_db has no counterpart. Use prepared statements or mysqli_query instead
    • mysql_db_name & mysql_list_dbs support has been dropped in favour of SQL's SHOW DATABASES
    • mysql_list_tables support has been dropped in favour of SQL's SHOW TABLES FROM dbname
    • mysql_list_fields support has been dropped in favour of SQL's SHOW COLUMNS FROM sometable
    • mysql_db_query -> use mysqli_select_db() then the query or specify the DB name in the query
    • mysql_fetch_field($result, 5) -> the second parameter (offset) is not present in mysqli_fetch_field. You can use mysqli_fetch_field_direct keeping in mind the different results returned
    • mysql_field_flags, mysql_field_len, mysql_field_name, mysql_field_table & mysql_field_type -> has been replaced with mysqli_fetch_field_direct
    • mysql_list_processes has been removed. If you need thread ID use mysqli_thread_id
    • mysql_pconnect has been replaced with mysqli_connect() with p: host prefix
    • mysql_result -> use mysqli_data_seek() in conjunction with mysqli_field_seek() and mysqli_fetch_field()
    • mysql_tablename support has been dropped in favour of SQL's SHOW TABLES
    • mysql_unbuffered_query has been removed. See this article for more information Buffered and Unbuffered queries
    0 讨论(0)
  • 2020-11-21 05:47

    (I realise this is old, but it still comes up...)

    If you do replace mysql_* with mysqli_* then bear in mind that a whole load of mysqli_* functions need the database link to be passed.

    E.g.:

    mysql_query($query)
    

    becomes

    mysqli_query($link, $query)
    

    I.e., lots of checking required.

    0 讨论(0)
  • 2020-11-21 05:48

    Although this topic is a decade old, I still often require to 'backpatch' existing applications which relied upon the mysql extension — the original programmers were too lazy to refactor all their code, and just tell customers to make sure that they run the latest PHP 5.6 version available.

    PHP 5.6 is now officially deprecated; in other words, developers had a decade to get rid of their dependencies upon mysql and move to PDO (or, well, mysqli...). But... changing so much legacy code is expensive, and not every manager is willing to pay for the uncountable hours to 'fix' projects with dozens of thousands of lines.

    I've searched for many solutions, and, in my case, I often used the solution presented by @esty-shlomovitz — but in the meantime, I've found something even better:

    https://www.phpclasses.org/package/9199-PHP-Replace-mysql-functions-using-the-mysqli-extension.html

    (you need to register to download it, but that just takes a minute)

    These are just two files which act as drop-in replacements for the whole mysql extension and very cleverly emulate pretty much everything (using mysqli) without the need to worry much about it. Of course, it's not a perfect solution, but very likely it will work in 99% of all cases out there.

    Also, a good tutorial for dealing with the chores of migration (listing many of the common pitfalls when migrating) can also be found here: https://www.phpclasses.org/blog/package/9199/post/3-Smoothly-Migrate-your-PHP-Code-using-the-Old-MySQL-extension-to-MySQLi.html

    (if you're reading this in 2030 and the PHPclasses website is down, well, you can always try archive.org :-)

    Update: @crashwap noted on the comments below that you can also get the same code directly from GitHub. Thanks for the tip, @crashwap :-)

    0 讨论(0)
提交回复
热议问题