PHP異步非阻塞MySQL客戶端連接池
作者:Tinywan
客戶端透明地將這些查詢分布在一個(gè)可擴(kuò)展的可用連接池中,并使用100%的用戶態(tài)PHP,沒有外部擴(kuò)展依賴性(例如ext/mysqli,ext/pdo等)。
概述
AMPHP是一個(gè)事件驅(qū)動(dòng)的PHP庫(kù)集合,設(shè)計(jì)時(shí)考慮了纖程和并發(fā)性。amphp/mysql是一個(gè)異步MySQL客戶端。該庫(kù)通過在可用連接的可伸縮池中透明地分發(fā)查詢來(lái)實(shí)現(xiàn)并發(fā)查詢??蛻舳送该鞯貙⑦@些查詢分布在一個(gè)可擴(kuò)展的可用連接池中,并使用100%的用戶態(tài)PHP,沒有外部擴(kuò)展依賴性(例如ext/mysqli,ext/pdo等)。
特征
- 公開一個(gè)非阻塞API,用于并發(fā)發(fā)出多個(gè)MySQL查詢
- 透明的連接池克服了MySQL的基本同步連接協(xié)議
- MySQL傳輸編碼支持(gzip,TLS加密)
- 支持參數(shù)化預(yù)處理語(yǔ)句
- 帶有提交和回滾事件鉤子的嵌套事務(wù)
- 無(wú)緩沖結(jié)果以減少大型結(jié)果集的內(nèi)存使用
- 完整的MySQL協(xié)議支持,包括所有可用的異步命令
安裝
此包可以作為Composer依賴項(xiàng)安裝
composer require amphp/mysql
使用
入門使用
<?php
/**
* @desc mysql.php
* @author Tinywan(ShaoBo Wan)
* @date 2024/8/16 11:19
*/
declare(strict_types=1);
require 'vendor/autoload.php';
use Amp\Mysql\MysqlConfig;
use Amp\Mysql\MysqlConnectionPool;
$config = MysqlConfig::fromString(
"host=127.0.0.1 user=root password=123456 db=test"
);
$pool = new MysqlConnectionPool($config);
$statement = $pool->prepare("SELECT * FROM mall_member WHERE member_time = :member_time Limit 10");
$timeOne = microtime(true);
$result = $statement->execute(['member_time' => 0]);
foreach ($result as $key => $row) {
echo '[x] ['.$key.'] '.$row['member_name'].PHP_EOL;
}
$timeTwo = microtime(true);
echo '[x] Run Time Result : ' . ($timeTwo - $timeOne) . PHP_EOL;
執(zhí)行結(jié)果:
[x] [0] 12161435
[x] [1] 開源技術(shù)小棧
[x] [2] 12161435
[x] [3] 12161435
[x] [4] T1800082
[x] [5] 12161435
[x] [6] 12161435
[x] [7] 12161387
[x] [8] 12161235
[x] [9] 12161149
[x] Run Time Result : 0.045973062515259
迭代器
<?php
require 'support/bootstrap.php';
use Amp\Future;
use Amp\Mysql\MysqlConfig;
use Amp\Mysql\MysqlConnectionPool;
use function Amp\async;
$db = new MysqlConnectionPool(MysqlConfig::fromAuthority(DB_HOST, DB_USER, DB_PASS, DB_NAME));
$db->query("DROP TABLE IF EXISTS tmp");
/* Create table and insert a few rows */
/* we need to wait until table is finished, so that we can insert. */
$db->query("CREATE TABLE IF NOT EXISTS tmp (a INT(10), b INT(10))");
print "Table successfully created." . PHP_EOL;
$statement = $db->prepare("INSERT INTO tmp (a, b) VALUES (?, ? * 2)");
$future = [];
foreach (\range(1, 5) as $num) {
$future[] = async(fn () => $statement->execute([$num, $num]));
}
/* wait until everything is inserted */
$results = Future\await($future);
print "Insertion successful (if it wasn't, an exception would have been thrown by now)" . PHP_EOL;
$result = $db->query("SELECT a, b FROM tmp");
foreach ($result as $row) {
var_dump($row);
}
$db->query("DROP TABLE tmp");
$db->close();
事務(wù)支持
<?php
require 'support/bootstrap.php';
require 'support/generic-table.php';
use Amp\Mysql\MysqlConfig;
use Amp\Mysql\MysqlConnectionPool;
$db = new MysqlConnectionPool(MysqlConfig::fromAuthority(DB_HOST, DB_USER, DB_PASS, DB_NAME));
/* create same table than in 3-generic-with-yield.php */
createGenericTable($db);
$transaction = $db->beginTransaction();
$transaction->execute("INSERT INTO tmp VALUES (?, ? * 2)", [6, 6]);
$result = $transaction->execute("SELECT * FROM tmp WHERE a >= ?", [5]); // Two rows should be returned.
foreach ($result as $row) {
\var_dump($row);
}
$transaction->rollback();
// Run same query again, should only return a single row since the other was rolled back.
$result = $db->execute("SELECT * FROM tmp WHERE a >= ?", [5]);
foreach ($result as $row) {
\var_dump($row);
}
$db->close();
責(zé)任編輯:武曉燕
來(lái)源:
開源技術(shù)小棧