借助PHP Mysqli扩展实现MySQL数据库交互
【相關學習推薦:php編程(視頻)】
引言
前面給大家簡單介紹了如何在本地安裝 MySQL 以及通過命令行和 GUI 客戶端軟件與 MySQL 服務器進行交互。
在命令行可以通過命令與 MySQL 交互,在客戶端軟件可以通過圖形化界面與 MySQL 交互,那么在 PHP 程序中如何建立與 MySQL 的連接和交互呢?實際上,我們完全可以把 PHP 應用看作是 MySQL 服務器的客戶端,然后通過封裝好的 PHP 擴展包提供的 API 與 MySQL 服務器進行交互,就好像我們在命令行和客戶端軟件中所做的一樣,只不過現在這種交互由手動操作轉變成了通過編寫對應的 PHP 代碼來完成。
PHP MySQLi 擴展
PHP 官方提供了很多用于與 MySQL 服務器進行交互的擴展,從最早的 mysql 到后來增強版的 mysqli(更加安全),它們都是 PHP 函數式編程時代的擴展包,一般來說,本地 PHP 集成開發環境都會自帶 mysqli 擴展:
下面我們通過一個簡單的示例來演示如何通過 mysqli 擴展與 MySQL 服務器交互。
數據庫連接與查詢
示例代碼
在 php_learning 目錄下新增一個 mysql 子目錄,然后在該子目錄下新建一個 mysqli.php 文件,編寫一段通過 mysqli 擴展 API 建立數據庫連接和查詢的代碼:
<?php $host = '127.0.0.1'; // MySQL 服務器主機地址 $port = 3306; // MySQL 服務器進程端口號 $user = 'root'; // 用戶名 $password = 'root'; // 密碼 $dbname = 'test'; // 使用的數據庫名稱 // 通過 mysqli 擴展建立與 mysql 服務器的連接 $conn = mysqli_connect($host, $user, $password, $dbname, $port); // 在連接實例上進行查詢 $sql = 'SELECT * FROM `post`'; $res = mysqli_query($conn, $sql); // 獲取所有結果 $rows = mysqli_fetch_all($res); var_dump($rows); // 釋放資源 mysqli_free_result($res); // 關閉連接 mysqli_close($conn);
可以看到,通過 mysqli_connect 函數即可建立與 MySQL 數據庫的連接,我們傳入了5個參數,依次是數據庫主機、用戶名、密碼、數據庫名稱和端口號,建立連接成功后,就可以持有這個連接實例通過 mysqli_query 函數執行數據庫查詢了,我們將 SQL 語句作為第二個參數傳入,該函數的返回結果是一個查詢結果集實例,拿到這個實例之后,就可以通過 mysqli_fetch_* 系列函數獲取結果數據了。
這里我們通過 mysqli_fetch_all 函數獲取所有查詢結果,通過 php -S localhost:9000 啟動 PHP 內置 HTTP 服務器:
就可以在瀏覽器中通過 http://localhost:9000/mysql/mysqli.php 打印的查詢結果了:
優化渲染效果
這個時候頁面樣式可讀性很差,可以在源碼中打印輸出結果之前,插入一段 echo '<pre>' 代碼優化渲染效果:
// 獲取所有結果 $rows = mysqli_fetch_all($res); echo '<pre>'; var_dump($rows);
刷新瀏覽器頁面,就可以看到如下打印效果:
相關學習推薦:mysql教程(視頻)
設置字符編碼
這里有個小問題,那就是 Emoji 表情符號沒有正常顯示出來,亂碼了,我們可以像在命令行中設置默認字符編碼一樣,通過 mysqli_set_charset 函數設置字符編碼為 utf8mb4:
// 通過 mysqli 擴展建立與 mysql 服務器的連接 $conn = mysqli_connect($host, $user, $password, $dbname, $port); // 設置字符編碼為 utf8mb4 mysqli_set_charset($conn, 'utf8mb4'); ... // 獲取所有結果 $rows = mysqli_fetch_all($res); echo '<pre>'; var_dump($rows[2]);
刷新頁面就可以看到 Emoji 表情了:
返回關聯數組
目前返回的結果是索引數組,無法得知數值對應的字段名,要獲取完整的字段名與字段值映射,可以將傳入 mysqli_fetch_all 函數的第二個參數值設置為 MYSQLI_ASSOC 來實現(默認是 MYSQLI_NUM):
// 獲取所有結果(關聯數組) $rows = mysqli_fetch_all($res, MYSQLI_ASSOC); echo '<pre>'; var_dump($rows[2]);
返回單條結果
上面返回的都是多條結果(即使只返回一條記錄,返回的也是多維數組),有時候,我們只想返回結果集中的第一條結果,這時候可以通過 mysqli_fetch_row 函數來實現:
// 在連接實例上進行查詢 $sql = 'SELECT * FROM `post` WHERE id = 1'; $res = mysqli_query($conn, $sql); // 獲取所有結果 /* $rows = mysqli_fetch_all($res, MYSQLI_ASSOC); echo '<pre>'; var_dump($rows);*/ // 獲取單條結果 $row = mysqli_fetch_row($res); echo '<pre>'; var_dump($row);
刷新瀏覽器測試頁面,打印結果如下:
可以看到返回結果已經是一個一維數組了,只包含一條記錄。如果想要返回關聯數組結果,需要通過一個新的函數 mysqli_fetch_assoc 函數來實現:
// 獲取單條結果 // $row = mysqli_fetch_row($res); $row = mysqli_fetch_assoc($res); echo '<pre>'; var_dump($row);
對應的打印結果如下:
將返回結果映射到指定對象
除了返回數組格式結果外,還可以借助 mysqli_fetch_object 函數將數據庫查詢結果映射到指定對象實例并返回:
class Post
{
    public $id;
    public $title;
    public $content;
    public $created_at;
    public function __toString()
    {
        return '[#' . $this->id . ']' . $this->title;
    }
}
// 將數據庫返回結果映射到指定個對象
$post = mysqli_fetch_object($res, Post::class);
echo $post;
對應的打印結果如下,說明對象映射成功(調用了對象的魔術方法 __toString 打印輸出該對象):
避免 SQL 注入攻擊
在上述數據庫查詢操作中,我們直接將原生 SQL 語句傳遞給 MySQL 數據庫執行,如果 SQL 語句中包含了用戶傳遞的參數,則存在 SQL 注入風險,要避免 SQL 注入攻擊,在 mysqli 擴展中,可以通過構建預處理語句的方式實現:
首先通過 mysqli_prepare 函數構建包含占位符(替代具體參數值)的預處理 SQL 語句;然后通過 mysqli_stmt_bind_param 函數將參數值綁定到預處理語句;最后通過 mysqli_stmt_execute 函數執行填充參數值之后的完整 SQL 語句,由于底層做了轉化處理,所以這時候執行的 SQL 語句不存在 SQL 注入風險。
下面,我們以插入記錄到數據庫為例,演示如何通過預處理語句的方式與數據庫交互,提高代碼安全性。
插入記錄到數據庫
我們首先基于預處理語句編寫插入記錄到數據庫的代碼如下(基于上面的 $conn 連接實例):
// 插入記錄到數據庫
$sql = 'INSERT INTO `post` (title, content, created_at) VALUES (?, ?, ?)';
// 構建預處理 SQL 語句
$stmt = mysqli_prepare($conn, $sql);// 綁定參數值
$title = '這是一篇測試文章';
$content = '測試文章啊啊啊總結
以上是生活随笔為你收集整理的借助PHP Mysqli扩展实现MySQL数据库交互的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: iis php如何开启错误提示
- 下一篇: 4个小红书发布笔记小细节,教你怎么“蹭流
