colshrapnel/safemysql

处理MySQL查询的真正安全便捷方式。

v1.1.0 2018-05-16 10:40 UTC

This package is not auto-updated.

Last update: 2024-09-18 17:42:49 UTC


README

SafeMySQL是一个用于安全便捷处理MySQL查询的PHP类。

  • 之所以安全,是因为每个动态查询部分都通过占位符进入查询
  • 之所以便捷,是因为它使应用程序代码简短、有意义,没有无用的重复,使得它''额外''DRY

此类有三个主要特点

  • 与标准库不同,它使用类型提示占位符,用于可能放入查询中的所有内容
  • 与标准库不同,它不需要重复绑定、获取等操作,因为有帮助方法可以直接从查询中获取所需结果
  • 与标准库不同,它可以解析占位符,不仅限于整个查询,还可以在任意的查询部分,多亏了必不可少的parse()方法,使得复杂查询像常规查询一样简单和安全。

然而,它非常容易使用。您只需要学习一些东西

  1. 您必须始终通过占位符传递任何动态数据到查询中
  2. 每个占位符都必须标记数据类型。目前有六种类型
  • ?s ("字符串") - 字符串(也适用于DATEFLOATDECIMAL
  • ?i ("整数") - 名字说明了一切
  • ?n ("名称") - 标识符(表和字段名称)
  • ?a ("数组") - 用于IN()操作符的复杂占位符(替换为没有括号的'a','b','c'格式的字符串)
  • ?u ("更新") - 用于SET操作符的复杂占位符(替换为'字段'='值'格式的字符串)
  • ?p ("解析") - 特殊类型占位符,用于插入已解析的语句而无需任何处理,以避免双重解析。
  1. 为了直接从查询中获取数据,有用于最常用情况的帮助方法
  • 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维数组,即索引列,由键 => 值对组成
  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运算符的数组,以及用于INSERTUPDATE查询的数组。因此,我们需要多种不同的数据格式化方式。因此,我们需要一种方法来告诉驱动程序如何格式化特定数据。传统的预编译语句通常使用繁琐且重复的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);

这同样适用于像INSERTUPDATE这样的繁琐查询。

当然,我们还有一套辅助函数,可以将类型提示占位符转换为真正的杰出功能,使得几乎每个数据库调用都像一行或两行代码一样简单,用于所有常规的实际任务。