中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在PHP中使用PDO、mysqli擴展

發布時間:2021-05-26 12:42:45 來源:億速云 閱讀:176 作者:Leah 欄目:開發技術

如何在PHP中使用PDO、mysqli擴展?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

PDO

基本操作如下:

<?php
// PDO + MySQL
$servername = "localhost";
$username = "username";
$password = "password";
try{
  $pdo = new PDO('mysql:host=$servername;dbname=myDB', '$username',
   '$password');
  echo '連接成功';
}
catch(PDOExcepton $e){
  echo $e->getMessge();
}
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);
// PDO + SQLite
$pdo = new PDO('sqlite:/path/db/foo.sqlite');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);
//關閉連接
$pdo=null;

PDO 并不會對 SQL 請求進行轉換或者模擬實現并不存在的功能特性;它只是單純地使用相同的 API 連接不同種類的數據庫。

更重要的是,PDO 使你能夠安全的插入外部輸入(例如 ID)到你的 SQL 請求中而不必擔心 SQL 注入的問題。這可以通過使用 PDO 語句和限定參數來實現。

我們來假設一個 PHP 腳本接收一個數字 ID 作為一個請求參數。這個 ID 應該被用來從數據庫中取出一條用戶記錄。下面是一個錯誤的做法:

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO!

這是一段糟糕的代碼。你正在插入一個原始的請求參數到 SQL 請求中。這將讓被黑客輕松地利用[SQL 注入]方式進行攻擊。想一下如果黑客將一個構造的 id 參數通過像 http://domain.com/?id=1%3BDELETE+FROM+users 這樣的 URL 傳入。這將會使 $_GET[‘id'] 變量的值被設為 1;DELETE FROM users 然后被執行從而刪除所有的 user 記錄!因此,你應該使用 PDO 限制參數來過濾 ID 輸入。

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- 首先過濾您的數據 ,對于INSERT,UPDATE等特別重要
$stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- 通過PDO自動對SQL進行清理
$stmt->execute();

這是正確的代碼。它在一條 PDO 語句中使用了一個限制參數。這將對外部 ID 輸入在發送給數據庫之前進行轉義來防止潛在的 SQL 注入攻擊。

對于寫入操作,例如 INSERT 或者 UPDATE,進行數據過濾并對其他內容進行清理(去除 HTML 標簽,Javascript 等等)是尤其重要的。PDO 只會為 SQL 進行清理,并不會為你的應用做任何處理。

mysqli擴展

mysqli基本操作如下:

<?php
$servername = "localhost";
$username = "username";
$password = "password";
// 創建連接
$conn = new mysqli($servername, $username, $password);
// 檢測連接
if ($conn->connect_error) {
  die("連接失敗: " . $conn->connect_error);
} 
echo "連接成功";
?>

注意在以上面向對象的實例中 $connect_error 是在 PHP 5.2.9 和 5.3.0 中添加的。如果你需要兼容更早版本 請使用以下代碼替換:

// 檢測連接
if (mysqli_connect_error()) {
  die("數據庫連接失敗: " . mysqli_connect_error());
}

數據庫交互

<ul>
<?php
foreach ($db->query('SELECT * FROM table') as $row) {
  echo "<li>".$row['field1']." - ".$row['field1']."</li>";
}
?>
</ul>

這從很多方面來看都是錯誤的做法,主要是由于它不易閱讀又難以測試和調試。而且如果你不加以限制的話,它會輸出非常多的字段。

其實還有許多不同的解決方案來完成這項工作 — 取決于你傾向于 面向對象編程(OOP)還是函數式編程 — 但必須有一些分離的元素。

來看一下最基本的做法:

<?php
function getAllFoos($db) {
  return $db->query('SELECT * FROM table');
}
foreach (getAllFoos($db) as $row) {
  echo "<li>".$row['field1']." - ".$row['field1']."</li>"; 
}

這是一個不錯的開頭。將這兩個元素放入了兩個不同的文件于是你得到了一些干凈的分離。
創建一個類來放置上面的函數,你就得到了一個「Model」。創建一個簡單的.php文件來存放表示邏輯,你就得到了一個「View」。這已經很接近 MVC — 一個大多數框架常用的面向對象的架構。

//foo.php

<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
// 使模板可見
include 'models/FooModel.php';
// 實例化類
$fooModel = new FooModel($db);
// Get the list of Foos
$fooList = $fooModel->getAllFoos();
// 顯示視圖
include 'views/foo-list.php';

//models/FooModel.php

<?php
class FooModel
{
  protected $db;
  public function __construct(PDO $db)
  {
    $this->db = $db;
  }
  public function getAllFoos() {
    return $this->db->query('SELECT * FROM table');
  }
}

//views/foo-list.php

<?php foreach ($fooList as $row): ?>
  <?= $row['field1'] ?> - <?= $row['field1'] ?>
<?php endforeach ?>

許多框架都提供了自己的數據庫抽象層,其中一些是設計在 PDO 的上層的。這些抽象層通常將你的請求在 PHP 方法中包裝起來,通過模擬的方式來使你的數據庫擁有一些之前不支持的功能。這種抽象是真正的數據庫抽象,而不單單只是 PDO 提供的數據庫連接抽象。這類抽象的確會增加一定程度的性能開銷,但如果你正在設計的應用程序需要同時使用 MySQL,PostgreSQL 和 SQLite 時,一點點的額外性能開銷對于代碼整潔度的提高來說還是很值得的。

看完上述內容,你們掌握如何在PHP中使用PDO、mysqli擴展的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三门峡市| 奉新县| 白水县| 新营市| 和平区| 阜南县| 内江市| 文成县| 西畴县| 胶州市| 河东区| 乐亭县| 新密市| 乐东| 赤城县| 乐清市| 宜章县| 三穗县| 山丹县| 涞水县| 汽车| 镇雄县| 潼关县| 卫辉市| 黄冈市| 永安市| 综艺| 大荔县| 永兴县| 盖州市| 陇南市| 开封市| 秀山| 额尔古纳市| 西昌市| 信丰县| 岚皋县| 岳西县| 罗江县| 阿瓦提县| 云和县|