PHP中的MySQLi擴展學習(一)MySQLi介紹 https://www.php.net/manual/zh/mysqli.quickstart.dual-interface.php

關於 PDO 的學習我們告一段落,從這篇文章開始,我們繼續學習另外一個 MySQL 擴展,也就是除了 PDO 之外的最核心的 MySQLi 擴展。可以說它的祖先,也就是 MySQL(原始) 擴展是我們很多人剛開始學習 PHP 時連接數據庫的入門導師。不過隨着時代的變遷,MySQL(原始) 擴展在 PHP7 中已經被徹底廢棄了。現在如果想要使用過程式的代碼來操作數據庫,只能使用 mysqli 擴展了。當然,mysqli 擴展也是支持面向對象式的寫法的。

什麼是 MySQLi

MySQLi 擴展允許我們訪問 MySQL4.1 及以上版本的數據庫所提供的功能。它是專門針對於 MySQL 數據庫的,不像 PDO 可以通過不同的 dns 來連接不同的數據庫。

與 MySQL 和 PDO 的區別與聯繫

首先,我們還是回顧一下最早的 MySQL 擴展。

  • 只面向過程

  • 不支持 存儲過程 、 多語句執行 、 預處理語句

  • PHP7 中已經刪除了並且完全不支持

然後是 PDO 。

  • 僅支持面向對象方式使用

  • 可以連接多種數據庫,切換數據庫帶來的變更少,甚至可能不用修改代碼

  • 支持 存儲過程 、 多語句執行 、 預處理語句

最後就是 MySQLi 。

  • 支持面向對象和麪向過程兩種寫法

  • 僅支持 MySQL 數據庫

  • 支持 存儲過程 、 多語句執行 、 預處理語句

  • 跟隨 PHP 及 MySQL 的版本更新,可以更快速地支持更多的 MySQL 高級特性

從它們三個的這些特點來看,MySQL(原始)擴展肯定是不推薦了,就算是老的項目,只要是支持 PDO 或 MySQLi 的 PHP 版本,都應該考慮將數據庫的連接轉換成這兩種方式之一。如果你還在 PHP5 的環境中學習 MySQL(原始)擴展的使用的話,也可以放下了。

而對於 PDO 和 MySQLi 的選擇來說,就仁者見仁智者見智了。本身它們其實並沒有什麼太大的差別,不過現代化的大型框架中基本都會將 PDO 作爲默認的數據庫連接來進行封裝,畢竟它的可移植性可以方便這些通用框架連接不同的數據庫。而一些小型的框架或項目中,還是能夠見到 MySQLi 的身影。當然,小衆並不意味着不好,就像日常開發中,我們很少會在 PHP 環境中使用別的數據庫,那麼在自己的小項目中完全使用一套 MySQLi 來操作數據庫反而更加地方便快捷。同時,老項目如果要切換到 PHP7 版本的話,如果之前使用的是 MySQL(原始)連接的數據庫,也能夠快速地將 MySQL(原始)的代碼很方面地替換到 MySQLi 。

擴展的安裝及 MySQL8 需要注意的地方

MySQLi 的擴展是隨 PHP 源碼一起發佈的,我們在編譯 PHP 的時候加上 --with-mysqli 就可以了。現在默認的數據庫驅動都是使用的 mysqlnd ,libmysql 也已經基本淘汰了。所以在編譯時不需要再加上其它的參數,直接進行編譯即可。

在連接 MySQL8 的時候需要注意,因爲 MySQL8 服務器會默認使用 caching_sha2_password 作爲密碼的加密。而 PHP7.2.4 之前的版本中的 MySQLi 會使用 mysql_native_password 來對連接密碼進行加密,這樣就會導致無法連接上數據庫。大家可以修改 my.cnf 文件,設置 default_authentication_plugin=mysql_native_password ,讓 MySQL8 也使用 mysql_native_password 來加密用戶密碼。

面向過程式

上文說過,MySQLi 是支持兩種寫法的,也就是面向對象和麪向過程。簡單地理解就是一種是 MySQL(原始)擴展的寫法,另一種寫法是類似於 PDO 的寫法。我們先來看看面向過程的寫法。

$mysqli = mysqli_connect("localhost", "root", "", "blog_test");
$res = mysqli_query($mysqli, "SELECT * FROM zyblog_test_user");
$row = mysqli_fetch_assoc($res);
print_r($row);

是不是感覺 MySQL(原始)擴展的代碼要移植過來真的很方便。方法名上全部改成 mysqli_xxx 就可以了。

面向對象式

面向對象式的就有點像 PDO 。我們要先獲得一個連接句柄類,然後操作這個類就可以了。

$mysqli = new mysqli("localhost", "root", "", "blog_test");
$res = $mysqli->query("SELECT * FROM zyblog_test_user");
$row = $res->fetch_assoc();
print_r($row);

面向對象和麪向過程混用

另外,這兩種方式還可以混合使用,不過並不推薦。混合起來使用的話很容易讓看代碼的人暈頭轉向。所以,最好還是在一個項目中就堅持使用一種方式。

$mysqli = new mysqli("localhost", "root", "", "blog_test");
$res = mysqli_query($mysqli, "SELECT * FROM zyblog_test_user");
$row = $res->fetch_assoc();
print_r($row);

在這段代碼中,我們實例化了一個 mysqli 對象,然後使用面向過程的 mysqli_query() 函數來執行語句,接着又使用面向對象的方式來獲取結果集。是不是很亂?但是它是可以正常運行的。

總結

從上面的內容中可以看出,PDO 的特點是支持多種不同類型的數據庫,就像 Java 中的 JDBC 一樣。而 MySQLi 雖然只支持 MySQL 數據庫,但它卻可以同時支持面向對象和麪向過程兩種寫法。是我們針對老項目代碼進行升級優化的好幫手。同時,它還是現在入門 PHP 學習相關數據庫操作的首選。在接下來的文章中,我們將默認只使用 面向對象 式的寫法來繼續學習 MySQLi 擴展相關的知識。

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/4.PHP中的MySQLi擴展學習(一)MySQLi介紹.php

參考文檔:

https://www.php.net/manual/zh/mysqli.requirements.php

https://www.php.net/manual/zh/mysqli.installation.php

https://www.php.net/manual/zh/mysqli.overview.php

https://www.php.net/manual/zh/mysqli.quickstart.dual-interface.php

各自媒體平臺均可搜索【硬核項目經理】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章