為什麼要對比這兩種不同模式的客戶端?
非同步 MySQL 回撥客戶端是雖然在 Swoole 1.8.6 版本就已經發布了,
但是非同步回撥的層層巢狀,讓編碼變得很彆扭。
如今 Swoole 4.3 版本都已經發布了,並且已經支援協程化的 MySQL 客戶端,
這意味著可以完全採用同步編碼的模式,來進行程式開發了,
對於開發者來說這是一個大好的訊息。
而且在 Swoole 4.3 版本之後,就已經移出了非同步回撥客戶端,
官方也一直推薦使用協程客戶端進行編碼。
一、Swoole 協程 MySQL 客戶端
從 Swoole 4.0 版本開始提供了完整的協程,
應用層可以使用完全的同步模式的程式設計方式,底層自動實現非同步 IO。
Swoole 的 MySQL 協程客戶端需要在協程的上下文環境下執行。
具體的使用方法直接看下面的示例即可。
1. 連線 MySQL 資料庫
<?php
co::create(function() {
$swoole_mysql = new Swoole\Coroutine\MySQL();
$swoole_mysql->connect([
'host' => 'mysql',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'database' => 'fastadmin',
]);
$res = $swoole_mysql->query('select sleep(1)');
// 新增
// 更新
// 查詢
// 刪除
// 事務操作
// ......
});
2. 新增操作
<?php
co::create(function() {
$stmt = $db->prepare('INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES (?, ?, ?');
if ($stmt == false){
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(['學習 PHP', '學習 PHP', date("Y-m-d")]);
var_dump($ret2);
}
});
3. 查詢操作
<?php
co::create(function() {
$res = $swoole_mysql->query('SELECT * FROM runoob_tbl WHERE runoob_id=1');
if($res === false) {
return;
}
foreach ($res as $value) {
echo $value['runoob_title'];
}
});
4. 更新操作
<?php
co::create(function() {
$stmt = $db->prepare('UPDATE runoob_tbl SET runoob_title=? WHERE runoob_id=?');
if ($stmt == false){
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(['學習 C++', 1]);
var_dump($ret2);
}
});
5. 刪除操作
<?php
co::create(function() {
$stmt = $db->prepare('DELETE FROM runoob_tbl WHERE runoob_id=1');
if ($stmt == false){
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(['學習 C++', 1]);
var_dump($ret2);
}
});
6. 事務操作
<?php
co::create(function() {
$db->begin();
$stmt = $db->prepare('INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES (?, ?, ?');
if ($stmt == false){
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(['學習 PHP', '學習 PHP', date("Y-m-d")]);
var_dump($ret2);
}
$stmt = $db->prepare('UPDATE runoob_tbl SET runoob_title=? WHERE runoob_id=?');
if ($stmt == false){
var_dump($db->errno, $db->error);
$db->rollback();
} else {
$ret2 = $stmt->execute(['學習 C++', 1]);
var_dump($ret2);
}
$db->commit();
});
三、Swoole 非同步回撥 MySQL 客戶端
Swoole 在 1.8.6 版本提供了全新的非同步 MySQL 客戶端,底層實現了 MySQL 通訊協議。
無需依賴其他第三方庫,如 libmysqlclient
, mysqlnd
, mysqli
等。
無需通過 --enable-async-mysql
編譯引數開啟。
Swoole 的 MySQL 非同步回撥客戶端的使用示例直接看下文即可。
注:非同步回撥客戶端在 Swoole 4.3 版本已經被移出了(標誌著已經過時了),建議使用協程客戶端。
1. 連線 MySQL 資料庫
<?php
$db = new swoole_mySQL();
$server = [
'host' => 'mysql',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'database' => 'fastadmin',
'charset' => 'utf8',
'timeout' => 2
];
$db->connect($server, function ($db, $r) {
if ($r === false) {
var_dump($db->connect_errno, $db->connect_errno);
die();
}
// 新增
// 更新
// 查詢
// 刪除
// 事務操作
// ......
)
2. 新增操作
<?php
// 新增
$sql = "INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES (\"學習 PHP\", \"菜鳥教程\", NOW())";
$db->query($sql, function(swoole_mySQL $db, $r) {
if ($r === false) {
echo "新增資料失敗, 錯誤資訊: " . $db->error . ", 錯誤碼: " . $db->errno . "\n";
} elseif ($r === true) {
echo "新增資料成功, ID為:" . $db->insert_id, ", 影響行數: " . $db->affected_rows . "\n";
}
$db->close();
});
3. 更新操作
<?php
// 修改
$sql = "UPDATE runoob_tbl SET runoob_title='學習 C++' WHERE runoob_id=1";
$db->query($sql, function(swoole_mySQL $db, $r) {
if ($r === false) {
echo "新增資料失敗, 錯誤資訊: " . $db->error . ", 錯誤碼: " . $db->errno . "\n";
} elseif ($r === true) {
echo "新增資料成功, ID為:" . $db->insert_id, ", 影響行數: " . $db->affected_rows . "\n";
}
var_dump($r);
$db->close();
});
4. 查詢操作
<?php
// 查詢
$sql = "SELECT * FROM runoob_tbl WHERE runoob_id=1";
$db->query($sql, function(swoole_mySQL $db, $r) {
if ($r === false) {
echo "新增資料失敗, 錯誤資訊: " . $db->error . ", 錯誤碼: " . $db->errno . "\n";
}
var_dump($r);
$db->close();
});
5. 刪除操作
<?php
// 刪除
$sql = "DELETE FROM runoob_tbl WHERE runoob_id=1";
$db->query($sql, function(swoole_mySQL $db, $r) {
if ($r === false) {
echo "新增資料失敗, 錯誤資訊: " . $db->error . ", 錯誤碼: " . $db->errno . "\n";
}
var_dump($r);
$db->close();
});
6. 事務操作
<?php
// 事務
$db->begin(function(swoole_mySQL $db, $r) {
$sql = "INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES (\"學習 PHP\", \"菜鳥教程\", NOW())";
$db->query($sql, function(swoole_mySQL $db, $r) {
if ($r === true) {
$sql = "UPDATE runoob_tbl SET runoob_title1='學習 C++' WHERE runoob_id=5";
$db->query($sql, function(swoole_mySQL $db, $r){
if ($r === true) {
$db->commit(function(swoole_mySQL $db, $r) {
if ($r === true) {
echo "commit ok \n";
}
});
}
if ($r === false) {
$db->rollback(function(swoole_mySQL $db, $r) {
if ($r === true) {
echo "commit failed, rollback success \n";
}
});
}
$db->close();
});
}
});
});
四、參考文件
五、總結
- 在 Swoole 4.3 版本以後已經移出了非同步回撥模組了。
- 以後的開發可以直接協程的客戶端進行編碼了。
- 協程客戶端需要在協程的上下文環境中進行編碼。
- 不建議再使用非同步回撥模組。