簡體   English   中英

將類從 mysql 遷移到 mysqli

[英]Migrate class from mysql to mysqli

我有一個簡單的問題。 我有那個用 mysql 擴展編寫的類,我的問題是如何將該類從 mysql 遷移到 mysqli 面向對象的風格,而不是程序化的。 我是這個 mysqli 擴展的新手。

<?php
    class DBController {
        private $host = "";
        private $user = "";
        private $password = "";
        private $database = "";

        function __construct() {
            $conn = $this->connectDB();
            if(!empty($conn)) {
                $this->selectDB($conn);
            }
        }

        function connectDB() {
            $conn = mysql_connect($this->host,$this->user,$this->password);
            return $conn;
        }

        function selectDB($conn) {
            mysql_select_db($this->database,$conn);
        }

        function runQuery($query) {
            $result = mysql_query($query);
            while($row=mysql_fetch_assoc($result)) {
                $resultset[] = $row;
            }       
            if(!empty($resultset))
                return $resultset;
        }

        function numRows($query) {
            $result  = mysql_query($query);
            $rowcount = mysql_num_rows($result);
            return $rowcount;   
        }
    }
?>

擁有這樣的類是一個非常好的主意,但不幸的是,從mysql_* API 轉移到mysqli類並不是那么簡單。 它需要大量代碼重寫和思維轉變。

如果您計划從mysql_* API 升級,這可能意味着您一直使用 PHP 4。 如果您使用的是 PHP 5,那么您正在使用 PHP 4 的思維方式。 從那時起,PHP 取得了長足的進步。 我們現在有了合適的類、命名空間、更好的錯誤報告等。當涉及到數據庫交互時,我們現在有了兩個新的擴展:mysqli 和 PDO。 在這兩個中,您應該使用 PDO。 但是,如果您使用的是像您嘗試創建的包裝類那樣從 mysqli 更改為 PDO 應該非常容易。 僅出於這個原因,這樣的包裝類是一個好主意。

mysqli 擴展的主要原因是保留舊擴展的熟悉語法並添加必要的新功能,例如准備好的語句和正確的錯誤報告。 如果您習慣於將 PHP 變量直接放入 SQL 查詢中,那么您必須改變您的思維方式。 您現在應該使用參數化查詢並單獨綁定值。

改進后的類的一個簡單示例如下:

<?php

class DBController {
    /**
     * mysqli instance
     *
     * @var \mysqli
     */
    private $mysqli;

    public function __construct(
        $host = null,
        $username = null,
        $passwd = null,
        $dbname = null,
        $charset = 'utf8mb4',
        $port = null,
        $socket = null
    ) {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $this->mysqli = new \mysqli($host, $username, $passwd, $dbname, $port, $socket);
        $this->mysqli->set_charset($charset);
    }

    public function runQuery(string $sql, array $params = []): ?array {
        $stmt = $this->mysqli->prepare($sql);
        if ($params) {
            $stmt->bind_param(str_repeat("s", count($params)), ...$params);
        }
        $stmt->execute();
        if ($result = $stmt->get_result()) {
            return $result->fetch_all(MYSQLI_BOTH);
        }
        return null;
    }
}

警告:這不是此類包裝器類的完整實現。 您很可能需要實現其他方法並根據需要添加更多邏輯。 這僅用於演示目的。

首先,在construct方法中,我們應該執行3個步驟。 啟用錯誤報告,創建mysqli類的實例並設置正確的字符集(使用 MySQL 5.5 中添加的utf8mb4 ,現在是標准字符集)。

您的runQuery()方法現在接受 2 個參數。 第一個是使用占位符而不是內插值的 SQL 查詢,第二個是要綁定的值的數組。

很可能您不需要selectDB()並且您絕對不需要numRows() 如果您想知道檢索到的數組中的行數,您可以使用count()在 PHP 中計算它們。

使用這樣的類非常簡單。

$db = new DBController('localhost', 'username', 'password', 'db_name');
$result = $db->runQuery('SELECT Id, Name FROM table1 WHERE uuid=?', ['myuuid']);
if ($result) {
    // Get the name of found record
    echo $result[0]['Name'];
} else {
    echo 'No records found';
}

如果您想將實現切換到 PDO,您可以替換該類,而無需更改您使用它的方式。

class DBController {
    /**
     * PDO instance
     *
     * @var \PDO
     */
    private $pdo;

    public function __construct(
        $host = null,
        $username = null,
        $passwd = null,
        $dbname = null,
        $charset = 'utf8mb4',
        $port = null,
        $socket = null
    ) {
        $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset;port=$port;socket=$socket";
        $options = [
            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_EMULATE_PREPARES => false,
        ];
        $this->pdo = new PDO($dsn, $username, $passwd, $options);
    }

    public function runQuery(string $sql, array $params = []): ?array {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
}

警告:這不是此類包裝器類的完整實現。 您很可能需要實現其他方法並根據需要添加更多邏輯。 這僅用於演示目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM