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