当前位置: 首页 > 文档资料 > Swoole 中文文档 >

Coroutine\MySQL

优质
小牛编辑
137浏览
2023-12-01

协程MySQL客户端。

!> 本客户端不再推荐使用,推荐使用 Swoole\Runtime::enableCoroutine + PDO或Mysqli 方式,即一键协程化原生 PHP 的 mysql 客户端。

!> 请勿同时使用Swoole1.x时代的异步回调写法和本协程MySQL客户端。

使用示例

Co\run(function () {
    $swoole_mysql = new Swoole\Coroutine\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);
});

defer特性

请参考并发Client一节。

存储过程

4.0.0版本后, 支持MySQL存储过程和多结果集获取。

MySQL8.0

Swoole-4.0.1或更高版本支持了MySQL8所有的安全验证能力, 可以直接正常使用客户端,而无需回退密码设定

4.0.1 以下版本

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

属性

serverInfo

连接信息,保存的是传递给连接函数的数组。

sock

连接使用的文件描述符。

connected

是否连接上了MySQL服务器。

connect_error

执行connect连接服务器时的错误信息。

connect_errno

执行connect连接服务器时的错误码,类型为整型。

error

执行MySQL指令时,服务器返回的错误信息。

errno

执行MySQL指令时,服务器返回的错误码,类型为整型。

affected_rows

影响的行数。

insert_id

最后一个插入的记录id

方法

connect()

建立MySQL连接。

Swoole\Coroutine\MySQL->connect(array $serverInfo): bool;

!> $serverInfo:参数以数组形式传递

[
    'host'        => 'MySQL IP地址',
    'user'        => '数据用户',
    'password'    => '数据库密码',
    'database'    => '数据库名',
    'port'        => 'MySQL端口 默认3306 可选参数',
    'timeout'     => '建立连接超时时间', // 仅影响connect超时时间,不影响query和execute方法,参考`客户端超时规则`
    'charset'     => '字符集',
    'strict_type' => false, //开启严格模式,query方法返回的数据也将转为强类型
    'fetch_mode'  => true,  //开启fetch模式, 可与pdo一样使用fetch/fetchAll逐行或获取全部结果集(4.0版本以上)
]

query()

执行SQL语句。

Swoole\Coroutine\MySQL->query(string $sql, float $timeout = 0): array|false;
  • 参数

    • string $sql

      • 功能:SQL语句
      • 默认值:无
      • 其它值:无
    • float $timeout

      • 功能:超时时间 【$timeout如果小于或等于0,表示永不超时。在规定的时间内MySQL服务器未能返回数据,底层将返回false,设置错误码为110,并切断连接】
      • 值单位:秒,最小精度为毫秒(0.001秒)
      • 默认值0
      • 其它值:无
      • 参考客户端超时规则
  • 返回值

    • 超时/出错返回false,否则 array 形式返回查询结果
  • 延迟接收

!> 设置defer后,调用query会直接返回true。调用recv才会进入协程等待,返回查询的结果。

  • 示例
Co\run(function () {
    $swoole_mysql = new Swoole\Coroutine\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);
});

prepare()

向MySQL服务器发送SQL预处理请求。

!> prepare必须与execute配合使用。预处理请求成功后,调用execute方法向MySQL服务器发送数据参数。

Swoole\Coroutine\MySQL->prepare(string $sql, float $timeout): Swoole\Coroutine\MySQL\Statement|false;
  • 参数

    • string $sql

      • 功能:预处理语句【使用?作为参数占位符】
      • 默认值:无
      • 其它值:无
    • float $timeout

      • 功能:超时时间
      • 值单位:秒,最小精度为毫秒(0.001秒)
      • 默认值0
      • 其它值:无
      • 参考客户端超时规则
  • 返回值

    • 失败返回false,可检查$db->error$db->errno判断错误原因
    • 成功返回Coroutine\MySQL\Statement对象,可调用对象的execute方法发送参数
  • 示例

Co\run(function () {
    $db = new Swoole\Coroutine\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);
    }
});

escape()

转义SQL语句中的特殊字符,避免SQL注入攻击。底层基于mysqlnd提供的函数实现,需要依赖PHPmysqlnd扩展。

!> 编译时需要增加--enable-mysqlnd来启用。

Swoole\Coroutine\MySQL->escape(string $str): string;
  • 参数

    • string $str
      • 功能:转义字符
      • 默认值:无
      • 其它值:无
  • 使用示例

Co\run(function () {
    $db = new Swoole\Coroutine\MySQL();
    $db->connect([
        'host'     => '127.0.0.1',
        'port'     => 3306,
        'user'     => 'root',
        'password' => 'root',
        'database' => 'test',
    ]);
    $data = $db->escape("abc'efg\r\n");
});

begin()

开启事务。与commitrollback结合实现MySQL事务处理。

Swoole\Coroutine\MySQL->begin(): bool;

!> 启动一个MySQL事务,成功返回true,失败返回false,请检查$db->errno获取错误码。

!> 同一个MySQL连接对象,同一时间只能启动一个事务;
必须等到上一个事务commitrollback才能继续启动新事务;
否则底层会抛出Swoole\MySQL\Exception异常,异常code21

  • 示例

    $db->begin();
    $db->query("update userinfo set level = 22 where id = 1");
    $db->commit();

commit()

提交事务。

!> 必须与begin配合使用。

Swoole\Coroutine\MySQL->commit(): bool;

!> 成功返回true,失败返回false,请检查$db->errno获取错误码。

rollback()

回滚事务。

!> 必须与begin配合使用。

Swoole\Coroutine\MySQL->rollback(): bool;

!> 成功返回true,失败返回false,请检查$db->errno获取错误码。

Statement->execute()

向MySQL服务器发送SQL预处理数据参数。

!> execute必须与prepare配合使用,调用execute之前必须先调用prepare发起预处理请求。

!> execute方法可以重复调用。

Swoole\Coroutine\MySQL\Statement->execute(array $params, float $timeout = -1): array|bool
  • 参数

    • array $params

      • 功能:预处理数据参数 【必须与prepare语句的参数个数相同。$params必须为数字索引的数组,参数的顺序与prepare语句相同】
      • 默认值:无
      • 其它值:无
    • float $timeout

      • 功能:超时时间 【在规定的时间内MySQL服务器未能返回数据,底层将返回false,设置错误码为110,并切断连接】
      • 值单位:秒,最小精度为毫秒(0.001秒)
      • 默认值-1
      • 其它值:无
      • 参考客户端超时规则
  • 返回值

    • 成功时返回 ture,如果设置 connectfetch_mode 参数为 true
    • 成功时返回 array 数据集数组,如不是上述情况时,
    • 失败返回false,可检查$db->error$db->errno判断错误原因
  • 使用示例

Co\run(function () {
    $db = new Swoole\Coroutine\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);
    }
});

Statement->fetch()

从结果集中获取下一行。

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为止, 否则将无法发起新的请求 (由于底层按需读取机制, 可节省内存)

Statement->fetchAll()

返回一个包含结果集中所有行的数组。

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();

Statement->nextResult()

在一个多响应结果语句句柄中推进到下一个响应结果 (如存储过程的多结果返回)。

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为止, 否则将无法发起新的请求 (由于底层按需读取机制, 可节省内存)