一个简单方便操作mysql的AR(Medoo)

因为最近换了工作,新公司使用的是版本较老的phalcon框架,框架自带的orm使用起来非常反人类不好用,本来想要自己码一个简单的mysql操作类来使用,但是无意中发现了Medoo这个好东西,所以在Medoo的基础上进行了一些魔改。


Medoo介绍

正如Medoo官网所说,Medoo是一个高效的轻量级mysql框架,相较于orm的重,它的轻(整个框架只有一个php类文件)是追求效率而又不想让php代码一眼望过去全是sql语句的小伙伴的较佳选择(也许还有其他更好的,本人暂时没发现,所以这里使用较佳)。


魔改原因

  1. 因为追求效率,而这个框架支持多种数据库(mysql、mssql、sqlite、oracle…),而我只使用mysql,强迫症原因所以要剔除对其他数据库的支持(虽然并不能快多少,但是聊胜于无);
  2. 尽管框架在判断使用的数据库为mysql后进行了一些配置上的设置,但是经过我实际使用,发现其对表面及字段名的包裹一样使用引号而不是反引号,这显然是不行的(历史遗留问题,很多字段名是mysql的关键字)。

开始魔改

直接修改源码显然是不科学的,所有我的魔改选择新建一个类文件,然后继承源码中的Medoo类,由于源码只有一个文件,所以操作起来方便很多。

解决第一个问题,去除对其他数据库的支持:

通过分析代码,发现Medoo对于其他数据库的支持主要来源于构造函数中的判断,由于源码中构造函数行数太多这里就不贴出来了,小伙伴们可以直接查看源码,下面直接上我的精简版。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 重构构造函数,只需支持mysql
public function __construct($db = 'db', $prefix = '')
{
// 获取需要操作的数据库配置
$config = config($db);

// 设置前缀
$this->prefix = $prefix;
$this->logging = true;

$dsn = "mysql:host={$config->host};port={$config->port};dbname={$config->dbname}";

// 获取pdo对象
try {
$this->pdo = new PDO(
$dsn,
$config->username,
$config->password,
[PDO::ATTR_CASE => PDO::CASE_NATURAL]
);

} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}

我将构造函数修改的比较简单,去除了所有判断,保留了选择多个数据库链接及设置前缀的功能,这样看起来清爽多了。


解决第二个问题,将包裹表面及字段的符号由引号更换为反引号:

通过分析,很容易就找到了对表名及字段进行拼接的两个方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
protected function columnQuote($string)
{
if (strpos($string, '.') !== false) {
return '"' . $this->prefix . str_replace('.', '"."', $string) . '"';
}

return '"' . $string . '"';
}

protected function tableQuote($table)
{
return '"' . $this->prefix . $table . '"';
}

修改后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 将字段名由引号包含改为反引号包含
protected function columnQuote($string)
{
if (strpos($string, '.') !== false) {
return '`' . $this->prefix . str_replace('.', '`.`', $string) . '`';
}

return '`' . $string . '`';
}

// 将表名由引号包含改为反引号包含
protected function tableQuote($table)
{
return '`' . $this->prefix . $table . '`';
}


综上所诉,我的问题都已经解决了,后期可能会继续完善,让增删改查等都支持链式操作。修改后的完整代码如下,也可以进入我的github直接下载,代码仓库中有完整的原生Medoo和修改后的文件以及使用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Medoo extends \Medoo\Medoo
{
// 重构构造函数,只需支持mysql
public function __construct($db = 'db', $prefix = '')
{
$config = \Phalcon\Di::getDefault()->get('config')->db->{$db};
$this->prefix = $prefix;
$this->logging = true;

$dsn = "mysql:host={$config->host};port={$config->port};dbname={$config->dbname}";

try {
$this->pdo = new PDO(
$dsn,
$config->username,
$config->password,
[PDO::ATTR_CASE => PDO::CASE_NATURAL]
);

} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}

// 将表名由引号包含改为反引号包含
protected function tableQuote($table)
{
return '`' . $this->prefix . $table . '`';
}

// 将字段名由引号包含改为反引号包含
protected function columnQuote($string)
{
if (strpos($string, '.') !== false) {
return '`' . $this->prefix . str_replace('.', '`.`', $string) . '`';
}

return '`' . $string . '`';
}
}