colshrapnel / safemysql
处理MySQL查询的真正安全便捷方式。
Requires
- php: >=5.0.0
This package is not auto-updated.
Last update: 2024-09-18 17:42:49 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, ...) - 返回1维数组,即一行
- getCol($query,$param1,$param2, ...) - 返回1维数组,即一列
- getAll($query,$param1,$param2, ...) - 返回2维数组,即行数组
- getInd($key,$query,$par1,$par2, ...) - 返回索引的2维数组,即行数组
- getIndCol($key,$query,$par1,$par2, ...) - 返回1维数组,即索引列,由键 => 值对组成
- 对于任何复杂情况,始终使用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
这样的繁琐查询。
当然,我们还有一套辅助函数,可以将类型提示占位符转换为真正的杰出功能,使得几乎每个数据库调用都像一行或两行代码一样简单,用于所有常规的实际任务。