为什么要对比这两种不同模式的客户端?

异步 MySQL 回调客户端是虽然在 Swoole 1.8.6 版本就已经发布了,
但是异步回调的层层嵌套,让编码变得很别扭。
如今 Swoole 4.3 版本都已经发布了,并且已经支持协程化的 MySQL 客户端,
这意味着可以完全采用同步编码的模式,来进行程序开发了,
对于开发者来说这是一个大好的消息。
而且在 Swoole 4.3 版本之后,就已经移出了异步回调客户端,
官方也一直推荐使用协程客户端进行编码。

Swoole 协程 Mysql 客户端

Swoole 4.0 版本开始提供了完整的协程,应用层可以使用完全的同步模式的编程方式,底层自动实现异步IO。
SwooleMySQL 协程客户端需要在协程的上下文环境下执行。
具体的使用方法直接看下面的示例即可。

  • 连接 Mysql 协程客户端
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)');
    
    // 新增
    // 更新
    // 查询
    // 删除
    // 事务操作
    // ......
});
  • 新增操作
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);
    }
});
  • 查询操作
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'];
    } 
});
  • 更新操作
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);
    }
});
  • 删除操作
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);
    }
});
  • 事务操作
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 编译参数开启。
SwooleMysql 异步回调客户端的使用示例直接看下文即可。

注:异步回调客户端在 Swoole 4.3 版本已经被移出了(标志着已经过时了),建议使用协程客户端。

  • 连接 Mysql 数据库
$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();
    }
    
    // 新增
    // 更新
    // 查询
    // 删除
    // 事务操作
    // ......
)
  • 新增操作
// 新增
$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();
});
  • 更新操作
// 修改
$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();
});
  • 查询操作
// 查询
$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();
});
  • 删除操作
// 删除
$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();
});
  • 事务操作
// 事务
$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 版本以后已经移出了异步回调模块了。
  • 以后的开发可以直接协程的客户端进行编码了。
  • 协程客户端需要在协程的上下文环境中进行编码。
  • 不建议在使用异步回调模块。

参考文档