PHP--MySQL簡明手冊
PHP 的MySQL連線
當用PHP訪問資料庫時,除了PHP自帶的資料庫驅動,我們一般還有兩種比較好的選擇:PDO和MySQLi。
注意:自PHP5.5開始,傳統的mysql擴充套件已經廢棄,只能使用PHP提供的MySQLi擴充套件或PDO擴充套件
PDO和MySQLi區別
PDO | MySQLi | |
---|---|---|
Database support | 12 different drivers | MySQL only |
API | OOP | OOP + procedural |
Connection | Easy | Easy |
Named parameters | Yes | No |
Object mapping | Yes | Yes |
Prepared statements (client side) | Yes | No |
Performance | Fast | Fast |
Stored procedures | Yes | Yes |
如果你的專案需要在多種資料庫中切換,建議使用 PDO;若選用MySQLi,在多種資料庫中切換時候,你需要重新編寫所有程式碼。
MySQLi專門針對MySQL設計的,所以MySQLi相對於PDO效能稍微好一些。
PHP 連線MySQL
MySQLi - 面向物件的連線方法
<?php $servername = "localhost"; $username = "username"; $password = "password"; // 建立連線 $conn = new mysqli($servername, $username, $password); // 檢測連線 if ($conn->connect_error) { die("連線失敗: " . $conn->connect_error); } echo "連線成功"; ?>
MySQLi - 面向過程的連線方法
<?php $servername = "localhost"; $username = "username"; $password = "password"; // 建立連線 $conn = mysqli_connect($servername, $username, $password); // 檢測連線 if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } echo "連線成功"; ?
PDO 的連線方法
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB",
$username, $password);
echo "連線成功";
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
關閉連線
連線在指令碼執行完後會自動關閉。可以使用以下程式碼來關閉連線:
MySQLi - 面向物件的關閉連線方法
$conn->close();
MySQLi - 面向過程的關閉連線方法
mysqli_close($conn);
PDO關閉連線的方法
$conn = null;
建立資料庫
使用 MySQLi 和 PDO 建立 MySQL 資料庫
使用CREATE DATABASE語句建立資料庫
MySQLi - 使用面向物件的方式建立資料庫
<?php
$servername = "localhost";
$username = "username";
$password = "password";
// 建立連線
$conn = new mysqli($servername, $username, $password);
// 檢測連線
if ($conn->connect_error) {
die("連線失敗: " . $conn->connect_error);
}
// 建立資料庫
$sql = "CREATE DATABASE myDB";
if ($conn->query($sql) === TRUE) {
echo "資料庫建立成功";
} else {
echo
"Error creating database: " . $conn->error;
}
$conn->close();
?>
**MySQLi-使用面向過程的方式建立資料庫 **
<?php
$servername = "localhost";
$username = "username";
$password = "password";
// 建立連線
$conn = mysqli_connect($servername,
$username, $password);
// 檢測連線
if (!$conn) {
die("連線失敗: " . mysqli_connect_error());
}
// 建立資料庫
$sql = "CREATE DATABASE myDB";
if (mysqli_query($conn, $sql)) {
echo "資料庫建立成功";
} else {
echo "Error
creating database: " . mysqli_error($conn);
}
mysqli_close($conn);
?>
PDO 建立資料庫
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// 設定 PDO 錯誤模式為異常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE DATABASE myDBPDO";
// 使用 exec() ,因為沒有結果返回
$conn->exec($sql);
echo "資料庫建立成功<br>";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
建立資料表
使用CREATE TABLE語句建立資料表
我們將建立一個名為 "MyGuests" 的表,有 5 個列: "id", "firstname", "lastname", "email" 和 "reg_date":
CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)
MySQLi - 使用面向物件的方式建立資料表
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname = "myDB";
// 建立連線
$conn =
new mysqli($servername, $username, $password, $dbname);
// 檢測連線
if ($conn->connect_error) {
die("連線失敗: " . $conn->connect_error);
}
// 使用 sql 建立資料表
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
if ($conn->query($sql) === TRUE) {
echo "Table MyGuests created successfully";
} else {
echo "建立資料表錯誤: " . $conn->error;
}
$conn->close();
?>
MySQLi - 使用面向過程的方式建立資料表
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = mysqli_connect($servername, $username, $password, $dbname);
// 檢測連線
if (!$conn) {
die("連線失敗: " . mysqli_connect_error());
}
// 使用 sql 建立資料表
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
if (mysqli_query($conn, $sql)) {
echo "資料表 MyGuests 建立成功";
} else {
echo "建立資料表錯誤: " . mysqli_error($conn);
}
mysqli_close($conn);
?>
PDO 建立資料表
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 設定 PDO 錯誤模式,用於丟擲異常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 使用 sql 建立資料表
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
// 使用 exec() ,沒有結果返回
$conn->exec($sql);
echo "資料表 MyGuests 建立成功";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
插入資料
插入語句
INSERT INTO table_name (column1, column2, column3,...)VALUES (value1, value2, value3,...)
MySQLi - 使用面向物件方式插入資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢測連線
if ($conn->connect_error) {
die("連線失敗: " . $conn->connect_error);
}
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]')";
if ($conn->query($sql) === TRUE) {
echo "新記錄插入成功";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
MySQLi - 使用面向過程方式插入資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = mysqli_connect($servername, $username, $password, $dbname);
// 檢測連線
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]')";
if (mysqli_query($conn, $sql)) {
echo "新記錄插入成功";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?>
POD 插入資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 設定 PDO 錯誤模式,用於丟擲異常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]')";
// 使用 exec() ,沒有結果返回
$conn->exec($sql);
echo "新記錄插入成功";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
插入多條資料
MySQLi - 使用面向物件方式插入多條資料
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname = "myDB";
// 建立連結
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢查連結
if ($conn->connect_error) {
die("連線失敗: " . $conn->connect_error);
}
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]');";
$sql .= "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Mary', 'Moe', '[email protected]');";
$sql .= "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Julie', 'Dooley', '[email protected]')";
if ($conn->multi_query($sql) === TRUE) {
echo "新記錄插入成功";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
MySQLi - 使用面向過程方式插入多條資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連結
$conn = mysqli_connect($servername, $username, $password, $dbname);
// 檢查連結
if (!$conn) {
die("連線失敗: " . mysqli_connect_error());
}
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]');";
$sql .= "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Mary', 'Moe', '[email protected]');";
$sql .= "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Julie', 'Dooley', '[email protected]')";
if (mysqli_multi_query($conn, $sql)) {
echo "新記錄插入成功";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?>
PDO 插入多條資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 開始事務
$conn->beginTransaction();
// SQL 語句
$conn->exec("INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]')");
$conn->exec("INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Mary', 'Moe', '[email protected]')");
$conn->exec("INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('Julie', 'Dooley', '[email protected]')");
// 提交事務
$conn->commit();
echo "新記錄插入成功";
}
catch(PDOException $e)
{
// 如果執行失敗回滾
$conn->rollback();
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
使用預處理語句插入多條資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢測連線
if ($conn->connect_error) {
die("連線失敗: " . $conn->connect_error);
} else {
$sql = "INSERT INTO MyGuests VALUES(?, ?, ?)";
// 為 mysqli_stmt_prepare() 初始化statement 物件
$stmt = mysqli_stmt_init($conn);
//預處理語句
if (mysqli_stmt_prepare($stmt, $sql)) {
// 繫結引數
mysqli_stmt_bind_param($stmt, 'sss', $firstname, $lastname, $email);
// 設定引數並執行
$firstname = 'John';
$lastname = 'Doe';
$email = '[email protected]';
mysqli_stmt_execute($stmt);
$firstname = 'Mary';
$lastname = 'Moe';
$email = '[email protected]';
mysqli_stmt_execute($stmt);
$firstname = 'Julie';
$lastname = 'Dooley';
$email = '[email protected]';
mysqli_stmt_execute($stmt);
}
}
?>
引數繫結
mysqli_stmt_bind_param($stmt, 'sss', $firstname, $lastname, $email);
該函式繫結引數查詢並將引數傳遞給資料庫。第二個引數是 "sss" 。以下列表展示了引數的型別。
- i - 整數
- d - 雙精度浮點數
- s - 字串
- b - 布林值
預處理語句
預處理:建立 SQL 語句模板併發送到資料庫。預留的值使用引數 '?' 標記 。資料庫解析,編譯,對SQL語句模板執行查詢優化,並存儲結果不輸出。最後,將應用繫結的值傳遞給引數("?" 標記),資料庫執行語句
相對直接執行SQL語句,預處理的優點:
- 預處理語句大大減少了分析時間,只做了一次查詢(雖然語句多次執行)。
- 繫結引數減少了伺服器頻寬,你只需要傳送查詢的引數,而不是整個語句。
- 預處理語句針對SQL注入是非常有用的,因為引數值傳送後使用不同的協議,保證了資料的合法性。
MySQLi 使用預處理語句
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢測連線
if ($conn->connect_error)
{
die("連線失敗: " . $conn->connect_error);
}
// 預處理及繫結
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES(?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// 設定引數並執行
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "新記錄插入成功";
$stmt->close();
$conn->close();
?>
PDO 使用預處理語句
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 設定 PDO 錯誤模式為異常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 預處理 SQL 並繫結引數
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
// 插入行
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
// 插入其他行
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
// 插入其他行
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "新記錄插入成功";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
查詢資料
MySQLi -使用面向物件方式查詢資料
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 建立連線
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢測連線
if ($conn->connect_error)
{
die("連線失敗: " . $conn->connect_error);
}
$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// 輸出每行資料
while($row = $result->fetch_assoc())
{
echo "<br> id: ". $row["id"]. " - Name: ". $row["firstname"]. " " . $row["lastname"];
}
} else {
echo "0 個結果";
}
$conn->close();
?>
PDO 查詢資料
<?php
echo "<table style='border: solid 1px black;'>";
echo "<tr><th>Id</th><th>Firstname</th><th>Lastname</th><th>Email</th><th>Reg date</th> </tr>";
class TableRows extends RecursiveIteratorIterator {
function __construct($it) {
parent::__construct($it, self::LEAVES_ONLY);
}
function current() {
return "<td style='width: 150px; border: 1px solid black;'>" .
parent::current(). "</td>";
}
function beginChildren() {
echo "<tr>";
}
function endChildren() {
echo "</tr>" . "\n";
}
}
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT * FROM MyGuests");
$stmt->execute();
// 設定結果集為關聯陣列
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) {
echo $v;
}
$dsn = null;
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
echo "</table>";
?>
使用 WHERE 子句
WHERE 子句用於提取滿足指定標準的的記錄。
語法:
SELECT column_name(s)
FROM table_name
WHERE column_name operator value
例子:
<?php
$con=mysqli_connect("localhost","username","password","database");
// 檢測連線
if (mysqli_connect_errno())
{
echo "連線失敗: " . mysqli_connect_error();
}
$sql = "SELECT * FROM Persons WHERE FirstName='Peter'";
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
echo $row['FirstName'] . " " . $row['LastName'];
echo "<br>";
}
?>
ORDER BY 關鍵詞
ORDER BY 關鍵詞用於對記錄集中的資料進行排序,預設為升序。
語法:
SELECT column_name(s)
FROM table_name
ORDER BY column_name(s) ASC|DESC
例子:
<?php
$con=mysqli_connect("localhost","username","password","database");
// 檢測連線
if (mysqli_connect_errno())
{
echo "連線失敗: " . mysqli_connect_error();
}
$sql = "SELECT * FROM Persons ORDER BY age";
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
echo $row['FirstName'];
echo " " . $row['LastName'];
echo " " . $row['Age'];
echo "<br>";
}
mysqli_close($con);
?>
根據兩列進行排序
可以根據多個列進行排序.
當按照多個列進行排序時,只有第一列的值相同時才使用第二列:
SELECT column_name(s)
FROM table_name
ORDER BY column1, column2
Update 更新資料
UPDATE 語句用於更新資料庫表中已存在的記錄。
語法:
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value
注意:如果省去 WHERE 子句,所有的記錄都會被更新!
假設已經建立了“Person表”:
FirstName | LastName | Age |
---|---|---|
Peter | Griffin | 35 |
Glenn | Quagmire | 33 |
對Person表更新
<?php
$con=mysqli_connect("localhost","username","password","database");
// 檢測連線
if (mysqli_connect_errno())
{
echo "連線失敗: " . mysqli_connect_error();
}
$sql = "UPDATE Persons SET Age=36 WHERE FirstName='Peter' AND LastName='Griffin'";
mysqli_query($con,$sql);
mysqli_close($con);
?>
更新後:
FirstName | LastName | Age |
---|---|---|
Peter | Griffin | 36 |
Glenn | Quagmire | 33 |
Delete 刪除資料
DELETE 語句用於從資料庫表中刪除行。
語法:
DELETE FROM table_name
WHERE some_column = some_value
注意:如果省去 WHERE 子句,所有的記錄都會被刪除!
假設有表Person
FirstName | LastName | Age |
---|---|---|
Peter | Griffin | 35 |
Glenn | Quagmire | 33 |
下面的例子刪除 "Persons" 表中所有 LastName='Griffin' 的記錄:
<?php
$con=mysqli_connect("localhost","username","password","database");
// 檢測連線
if (mysqli_connect_errno())
{
echo "連線失敗: " . mysqli_connect_error();
}
$sql = "DELETE FROM Persons WHERE LastName='Griffin'";
mysqli_query($con,$sql);
mysqli_close($con);
?>
刪除資料後:
FirstName | LastName | Age |
---|---|---|
Glenn | Quagmire | 33 |