首頁  >  文章  >  專題  >  借助PHP Mysqli擴充實現MySQL資料庫交互

借助PHP Mysqli擴充實現MySQL資料庫交互

coldplay.xixi
coldplay.xixi轉載
2020-09-07 09:20:022545瀏覽

借助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 擴充:

借助PHP Mysqli擴充實現MySQL資料庫交互

下面我們透過一個簡單的範例來示範如何透過mysqli 擴充功能與MySQL 伺服器互動。

資料庫連線與查詢

範例程式碼

php_learning 目錄下新增一個mysql#子目錄,然後在該子目錄下新建一個mysqli.php 文件,編寫一段透過mysqli 擴充API 建立資料庫連線和查詢的程式碼:

<?php $host = &#39;127.0.0.1&#39;;   // MySQL 服务器主机地址
$port = 3306;          // MySQL 服务器进程端口号
$user = &#39;root&#39;;         // 用户名
$password = &#39;root&#39;;     // 密码
$dbname = &#39;test&#39;;       // 使用的数据库名称

// 通过 mysqli 扩展建立与 mysql 服务器的连接
$conn = mysqli_connect($host, $user, $password, $dbname, $port);

// 在连接实例上进行查询
$sql = &#39;SELECT * FROM `post`&#39;;
$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 伺服器:

借助PHP Mysqli擴充實現MySQL資料庫交互

#就可以在瀏覽器中透過http://localhost:9000/mysql/mysqli.php 列印的查詢結果了:

借助PHP Mysqli擴充實現MySQL資料庫交互

優化渲染效果

這個時候頁面樣式可讀性很差,可以在原始碼中列印輸出結果之前,插入一段echo '<pre class="brush:php;toolbar:false">'</pre> 程式碼最佳化渲染效果:

// 获取所有结果
$rows = mysqli_fetch_all($res);
echo '<pre class="brush:php;toolbar:false">';
var_dump($rows);

刷新瀏覽器頁面,就可以看到如下列印效果:

借助PHP Mysqli擴充實現MySQL資料庫交互

##相關學習推薦:

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 class="brush:php;toolbar:false">';
var_dump($rows[2]);
刷新頁面就可以看到Emoji 表情了:

借助PHP Mysqli擴充實現MySQL資料庫交互

傳回關聯數組

目前傳回的結果是索引數組,無法得知數值對應的欄位名,要取得完整的字段名與字段值映射,可以將傳入

mysqli_fetch_all 函數的第二個參數值設為MYSQLI_ASSOC 來實現(預設是MYSQLI_NUM):

// 获取所有结果(关联数组)
$rows = mysqli_fetch_all($res, MYSQLI_ASSOC);
echo '<pre class="brush:php;toolbar:false">';
var_dump($rows[2]);

借助PHP Mysqli擴充實現MySQL資料庫交互

傳回單一結果

#上面傳回的都是多筆結果(即使只回傳一筆記錄,傳回的也是多維數組),有時候,我們只想回傳結果集中的第一個結果,這時候可以透過mysqli_fetch_row 函數來實現:

// 在连接实例上进行查询
$sql = 'SELECT * FROM `post` WHERE id = 1';
$res = mysqli_query($conn, $sql);

// 获取所有结果
/*
$rows = mysqli_fetch_all($res, MYSQLI_ASSOC);
echo '<pre class="brush:php;toolbar:false">';
var_dump($rows);*/

// 获取单条结果
$row = mysqli_fetch_row($res);
echo '<pre class="brush:php;toolbar:false">';
var_dump($row);
刷新瀏覽器測試頁面,列印結果如下:

借助PHP Mysqli擴充實現MySQL資料庫交互#

可以看到返回结果已经是一个一维数组了,只包含一条记录。如果想要返回关联数组结果,需要通过一个新的函数 mysqli_fetch_assoc 函数来实现:

// 获取单条结果
// $row = mysqli_fetch_row($res);
$row = mysqli_fetch_assoc($res);
echo '<pre class="brush:php;toolbar:false">';
var_dump($row);

对应的打印结果如下:

借助PHP Mysqli擴充實現MySQL資料庫交互

将返回结果映射到指定对象

除了返回数组格式结果外,还可以借助 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 打印输出该对象):

借助PHP Mysqli擴充實現MySQL資料庫交互

避免 SQL 注入攻击

在上述数据库查询操作中,我们直接将原生 SQL 语句传递给 MySQL 数据库执行,如果 SQL 语句中包含了用户传递的参数,则存在 SQL 注入风险,要避免 SQL 注入攻击,在 mysqli 扩展中,可以通过构建预处理语句的方式实现:

  1. 首先通过 mysqli_prepare 函数构建包含占位符(替代具体参数值)的预处理 SQL 语句;
  2. 然后通过 mysqli_stmt_bind_param 函数将参数值绑定到预处理语句;
  3. 最后通过 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資料庫交互的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:xueyuanjun.com。如有侵權,請聯絡admin@php.cn刪除