协程 MySQL 客户端。
本客户端不再推荐使用,推荐使用 Swoole\Runtime::enableCoroutine + PDO 或 Mysqli 方式,即一键协程化原生 PHP 的 MySQL 客户端。
请勿同时使用 Swoole1.x 时代的异步回调写法和本协程 MySQL 客户端。
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;
run(function () {
$swoole_mysql = new MySQL();
$swoole_mysql->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'user',
'password' => 'pass',
'database' => 'test',
]);
$res = $swoole_mysql->query('select sleep(1)');
var_dump($res);
});请参考并发 Client 一节。
从 4.0.0 版本后,支持 MySQL 存储过程和多结果集获取。
Swoole-4.0.1 或更高版本支持了 MySQL8 所有的安全验证能力,可以直接正常使用客户端,而无需回退密码设定
MySQL-8.0 默认使用了安全性更强的 caching_sha2_password 插件,如果是从 5.x 升级上来的,可以直接使用所有 MySQL 功能,如是新建的 MySQL, 需要进入 MySQL 命令行执行以下操作来兼容:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; flush privileges;
将语句中的 'root'@'localhost' 替换成你所使用的用户,password 替换成其密码.
如仍无法使用,应在 my.cnf 中设置 default_authentication_plugin = mysql_native_password
连接信息,保存的是传递给连接函数的数组。
连接使用的文件描述符。
是否连接上了 MySQL 服务器。
执行 connect 连接服务器时的错误信息。
执行 connect 连接服务器时的错误码,类型为整型。
执行 MySQL 指令时,服务器返回的错误信息。
执行 MySQL 指令时,服务器返回的错误码,类型为整型。
影响的行数。
最后一个插入的记录 id。
建立 MySQL 连接。
Swoole\Coroutine\MySQL->connect(array $serverInfo): bool
$serverInfo:参数以数组形式传递
[ 'host' => 'MySQL IP地址', // 若是本地UNIXSocket则应以形如`unix://tmp/your_file.sock`的格式填写 'user' => '数据用户', 'password' => '数据库密码', 'database' => '数据库名', 'port' => 'MySQL端口 默认3306 可选参数', 'timeout' => '建立连接超时时间', // 仅影响connect超时时间,不影响query和execute方法,参考`客户端超时规则` 'charset' => '字符集', 'strict_type' => false, //开启严格模式,query方法返回的数据也将转为强类型 'fetch_mode' => true, //开启fetch模式, 可与pdo一样使用fetch/fetchAll逐行或获取全部结果集(4.0版本以上) ]
执行 SQL 语句。
Swoole\Coroutine\MySQL->query(string $sql, float $timeout = 0): array|false
参数
功能:超时时间 【在规定的时间内 MySQL 服务器未能返回数据,底层将返回 false,设置错误码为 110,并切断连接】
值单位:秒,最小精度为毫秒(0.001 秒)
默认值:0
其它值:无
参考客户端超时规则
功能:SQL 语句
默认值:无
其它值:无
string $sql
float $timeout
返回值
超时 / 出错返回 false,否则 array 形式返回查询结果
延迟接收
设置 defer 后,调用 query 会直接返回 true。调用 recv 才会进入协程等待,返回查询的结果。
示例
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;
run(function () {
$swoole_mysql = new MySQL();
$swoole_mysql->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'user',
'password' => 'pass',
'database' => 'test',
]);
$res = $swoole_mysql->query('show tables');
if ($res === false) {
return;
}
var_dump($res);
});向 MySQL 服务器发送 SQL 预处理请求。
prepare 必须与 execute 配合使用。预处理请求成功后,调用 execute 方法向 MySQL 服务器发送数据参数。
Swoole\Coroutine\MySQL->prepare(string $sql, float $timeout): Swoole\Coroutine\MySQL\Statement|false;
参数
功能:超时时间
值单位:秒,最小精度为毫秒(0.001 秒)
默认值:0
其它值:无
参考客户端超时规则
功能:预处理语句【使用 ? 作为参数占位符】
默认值:无
其它值:无
string $sql
float $timeout
返回值
失败返回 false,可检查 $db->error 和 $db->errno 判断错误原因
成功返回 Coroutine\MySQL\Statement 对象,可调用对象的 execute 方法发送参数
示例
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;
run(function () {
$db = new MySQL();
$ret1 = $db->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'database' => 'test',
]);
$stmt = $db->prepare('SELECT * FROM userinfo WHERE id=?');
if ($stmt == false) {
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(array(10));
var_dump($ret2);
}
});转义 SQL 语句中的特殊字符,避免 SQL 注入攻击。底层基于 mysqlnd 提供的函数实现,需要依赖 PHP 的 mysqlnd 扩展。
编译时需要增加 --enable-mysqlnd 来启用。
Swoole\Coroutine\MySQL->escape(string $str): string
参数
功能:转义字符
默认值:无
其它值:无
string $str
使用示例
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;
run(function () {
$db = new MySQL();
$db->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'database' => 'test',
]);
$data = $db->escape("abc'efg\r\n");
});开启事务。与 commit 和 rollback 结合实现 MySQL 事务处理。
Swoole\Coroutine\MySQL->begin(): bool
启动一个 MySQL 事务,成功返回 true,失败返回 false,请检查 $db->errno 获取错误码。
同一个 MySQL 连接对象,同一时间只能启动一个事务;
必须等到上一个事务 commit 或 rollback 才能继续启动新事务;
否则底层会抛出 Swoole\MySQL\Exception 异常,异常 code 为 21。
示例
$db->begin();
$db->query("update userinfo set level = 22 where id = 1");
$db->commit();提交事务。
必须与 begin 配合使用。
Swoole\Coroutine\MySQL->commit(): bool
成功返回 true,失败返回 false,请检查 $db->errno 获取错误码。
回滚事务。
必须与 begin 配合使用。
Swoole\Coroutine\MySQL->rollback(): bool
成功返回 true,失败返回 false,请检查 $db->errno 获取错误码。
向 MySQL 服务器发送 SQL 预处理数据参数。
execute 必须与 prepare 配合使用,调用 execute 之前必须先调用 prepare 发起预处理请求。
execute 方法可以重复调用。
Swoole\Coroutine\MySQL\Statement->execute(array $params, float $timeout = -1): array|bool
参数
功能:超时时间 【在规定的时间内 MySQL 服务器未能返回数据,底层将返回 false,设置错误码为 110,并切断连接】
值单位:秒,最小精度为毫秒(0.001 秒)
默认值:-1
其它值:无
参考客户端超时规则
功能:预处理数据参数 【必须与 prepare 语句的参数个数相同。$params 必须为数字索引的数组,参数的顺序与 prepare 语句相同】
默认值:无
其它值:无
array $params
float $timeout
返回值
成功时返回 true,如果设置 connect 的 fetch_mode 参数为 true 时
成功时返回 array 数据集数组,如不是上述情况时,
失败返回 false,可检查 $db->error 和 $db->errno 判断错误原因
使用示例
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;
run(function () {
$db = new MySQL();
$ret1 = $db->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'database' => 'test',
]);
$stmt = $db->prepare('SELECT * FROM userinfo WHERE id=? and name=?');
if ($stmt == false) {
var_dump($db->errno, $db->error);
} else {
$ret2 = $stmt->execute(array(10, 'rango'));
var_dump($ret2);
$ret3 = $stmt->execute(array(13, 'alvin'));
var_dump($ret3);
}
});从结果集中获取下一行。
Swoole\Coroutine\MySQL\Statement->fetch(): ?array
Swoole 版本 >= 4.0-rc1,需在 connect 时加入 fetch_mode => true 选项
示例
$stmt = $db->prepare('SELECT * FROM ckl LIMIT 1');
$stmt->execute();
while ($ret = $stmt->fetch()) {
var_dump($ret);
}从 v4.4.0 的新 MySQL 驱动开始,fetch 必须使用示例代码的方式读到 NULL 为止,否则将无法发起新的请求 (由于底层按需读取机制,可节省内存)
返回一个包含结果集中所有行的数组。
Swoole\Coroutine\MySQL\Statement->fetchAll():? array
Swoole 版本 >= 4.0-rc1,需在 connect 时加入 fetch_mode => true 选项
示例
$stmt = $db->prepare('SELECT * FROM ckl LIMIT 1');
$stmt->execute();
$stmt->fetchAll();在一个多响应结果语句句柄中推进到下一个响应结果 (如存储过程的多结果返回)。
Swoole\Coroutine\MySQL\Statement->nextResult():? bool
返回值
成功时返回 TRUE
失败时返回 FALSE
无下一结果返回 NULL
示例
非 fetch 模式
$stmt = $db->prepare('CALL reply(?)');
$res = $stmt->execute(['hello mysql!']);
do {
var_dump($res);
} while ($res = $stmt->nextResult());
var_dump($stmt->affected_rows);fetch 模式
$stmt = $db->prepare('CALL reply(?)');
$stmt->execute(['hello mysql!']);
do {
$res = $stmt->fetchAll();
var_dump($res);
} while ($stmt->nextResult());
var_dump($stmt->affected_rows);从 v4.4.0 的新 MySQL 驱动开始,fetch 必须使用示例代码的方式读到 NULL 为止,否则将无法发起新的请求 (由于底层按需读取机制,可节省内存)