easyswoole 没有自带数据库封装类,但是可以根据自己的需求使用第三方的封装类或者自己封装。笔者使用的是 mysql 就从 github 自己下载 MysqliDb 结合swoole使用。
easyswoole 使用 MysqliDb 示例
- 从 GitHubhttps://github.com/joshcam/PHP-MySQLi-Database-Class下载MysqliDb 包放入
App/Vendor
下
在
Conf/Event
下的frameInitialize
方法中引入类$loader = AutoLoader::getInstance(); $loader->requireFile("App/Vendor/MysqliDb/MysqliDb.php");
在
App/Utility
下新建Mysql类,把mysql做成单例
namespace App\Utility;
use Conf\Config;
class Mysql {
protected $db;
protected static $instance;
function __construct()
{
$this->initMysqlConnection();
}
static function getInstance(){
if(!isset(self::$instance)){
self::$instance = new Mysql();
}
return self::$instance;
}
function getDb(){
if ($this->db instanceof \MysqliDb){
return $this->db;
}else {
return null;
}
}
public static function getLimit($page = 1, $page_num = 10){
if($page >= 1){
$limit = Array(($page-1)*$page_num, $page_num);
}else{
$limit = Array(0,$page_num);
}
return $limit;
}
public function initMysqlConnection() {
$conf = Config::getInstance()->getConf("MYSQL");
$this->db = new \MysqliDb(
$conf['HOST'],
$conf['USER'],
$conf['PASSWORD'],
$conf['DB_NAME']
);
} }
- 将数据库配置信息写入
Conf/Config.php
中对应的key中,上面的示例代码数据库参数是在 config 中的 key = MYSQL中 。在Conf/Config.php
中的userConf
方法中配置
private function userConf(){
return array(
"MYSQL"=>array(
"HOST" => "127.0.0.1",
"USER" => "root",
"PASSWORD" => "password",
"DB_NAME" => "dbname"
)
);
}
5 . 在类中调用
Mysql::getInstance()->getDb()
->where('id', '1', '=')
->get('mytable', 10, 'id, name');
注意
这种做法相当于第一次获取mysqli单例的时候创建数据库连接,用长连接避免每次请求都创建连接的开销,节省了时间和IO消耗,提升了PHP程序的性能。在cli环境下,PHP程序需要长时间运行,客户端与MySQL服务器之间的TCP连接是不稳定的。
- MySQL-Server会在一定时间内自动切断连接
- PHP程序遇到空闲期时长时间没有MySQL查询,MySQL-Server也会切断连接回收资源
- 其他情况,在MySQL服务器中执行kill process杀掉某个连接,MySQL服务器重启
这时PHP程序中的MySQL连接就失效了。如果仍然执行mysql_query,就会报一个“MySQL server has gone away”的错误。
解决办法:
修改mysqliDb第三方类,实现mysql断线重连。打开App/Vendor/MysqliDb/MysqliDb.php
,找到protected function _prepareQuery()
方法,修改成:
protected function _prepareQuery()
{
//change by xhx 2017年07月27日17:08:26
$stmt = $this->mysqli()->prepare($this->_query);
if(!$stmt){
$msg = $this->mysqli()->error . " query: " . $this->_query;
\Core\Component\Logger::console($msg);
\Core\Component\Logger::console("reconnect ");
//未做断线重连尝试次数校验请自己加逻辑。
$this->connect();
$stmt = $this->_prepareQuery();
}
if ($this->traceEnabled) {
$this->traceStartQ = microtime(true);
}
return $stmt;
}
总结:
用户可以根据自己的需求使用相应数据库的工具类,用类似的方法解决数据库断线重连的问题即可。