iandreyev / safemysqlplus
处理MySQL查询的真正安全、方便的方法。
Requires
- php: >=5.0.0
This package is auto-updated.
Last update: 2024-09-15 15:23:11 UTC
README
SafeMySQL是一个用于安全、方便处理MySQL查询的PHP类。
- 之所以安全,是因为每个动态查询部分都通过占位符进入查询
- 之所以方便,是因为它使得应用程序代码简短且具有意义,没有无用的重复,使它更加“额外”地遵循DRY原则
这个类有三个主要特点
- 与标准库不同,它使用类型提示占位符,用于可能放入查询的一切
- 与标准库不同,它不需要重复绑定、检索等,因为它提供了一系列辅助方法,可以直接从查询中获得所需的结果
- 与标准库不同,它可以解析占位符,不仅限于整个查询,还可以是任意的查询部分,这得益于不可或缺的parse()方法,使得复杂查询像常规查询一样简单、安全。
然而,它非常容易使用。你只需要学习一些东西
- 你必须始终通过占位符传递任何动态数据到查询中
- 每个占位符必须标记数据类型。目前有六种类型
- ?s ("字符串") - 字符串(也包括
DATE
、FLOAT
和DECIMAL
) - ?i ("整数") - 如其名所示
- ?n ("名称") - 标识符(表和字段名称)
- ?a ("数组") - 复杂占位符,用于
IN()
运算符(替换为'a','b','c'格式的字符串,不带括号) - ?u ("更新") - 复杂占位符,用于
SET
运算符(替换为'字段'='值','字段'='值'格式的字符串) - ?p ("解析") - 特殊类型占位符,用于插入已解析的语句,无需任何处理,以避免重复解析。
- 为了从查询中直接获取数据,有一系列辅助方法用于最常用的
- query($query,$param1,$param2, ...) - 返回mysqli资源。
- getOne($query,$param1,$param2, ...) - 返回标量值
- getRow($query,$param1,$param2, ...) - 返回一维数组,一行
- getCol($query,$param1,$param2, ...) - 返回一维数组,一列
- getAll($query,$param1,$param2, ...) - 返回二维数组,行数组
- getInd($key,$query,$par1,$par2, ...) - 返回索引二维数组,行数组
- getIndCol($key,$query,$par1,$par2, ...) - 返回一维数组,索引列,由键=>值对组成
- 对于任何复杂情况,始终使用parse()方法。然后插入
其余的就像平常一样 - 只需创建一个带有占位符的常规SQL(),然后获取结果
$name = $db->getOne('SELECT name FROM table WHERE id = ?i',$_GET['id']);
$data = $db->getInd('id','SELECT * FROM ?n WHERE id IN (?a)','table', array(1,2));
$data = $db->getAll("SELECT * FROM ?n WHERE mod=?s LIMIT ?i",$table,$mod,$limit);
这个类的主要特点是带有类型提示的占位符。这比仅仅在预处理语句中使用序号占位符又前进了一大步。简单地说,查询的动态部分不仅限于标量数据!在现实生活中,我们不得不添加标识符、用于IN
运算符的数组,以及用于INSERT
和UPDATE
查询的数组。所以——我们需要很多不同类型的数据格式化。因此,我们需要一种方法来告诉驱动器如何格式化这些特定的数据。传统的预处理语句通常使用繁琐且重复的bind_*函数。但有一种更加优雅且实用的方法——就是在占位符本身设置类型。这不是什么新东西——众所周知的printf()
函数就是使用相同的机制。所以,我犹豫着是否要借鉴这样一个绝妙的想法。
要实现这样的功能,毫无疑问,必须拥有自己的查询解析器。没问题,这不是什么大问题。但好处是无穷无尽的。看看Stack Overflow上所有的问题,开发者们都在徒劳地尝试绑定字段名。看吧——有了标识符占位符,添加字段值就像一样简单。
$field = $_POST['field']; $value = $_POST['value']; $sql = "SELECT * FROM table WHERE ?n LIKE ?s"; $data = $db->query($sql,$field,"%$value%");
没有什么是更简单的了!
当然,我们会为常见类型提供占位符——字符串和数字。但既然我们已经开始发明新的占位符——让我们再发明一些!
在创建预处理查询时,另一个麻烦是用于IN运算符的数组。每个人都试图用自己的方法来做,但类型提示占位符使得这就像添加一个字符串一样简单。
$array = array(1,2,3); $data = $db->query("SELECT * FROM table WHERE id IN (?a)",$array);
对于像INSERT
和UPDATE
这样的繁琐查询也是如此。
当然,我们还提供了一套辅助函数,可以将类型提示占位符转换为真正的精彩,使得几乎每个数据库调用都像一行或两行代码那样简单,用于所有常见的实际任务。