我开发了一个项目,在该项目下使用了几个 sql 查询。现在我想监控一些查询以提高安全性。所以我希望每个查询都首先通过一个函数。由于查询太多,所以我无法返回并编辑每个文件和查询。有没有一种方法可以在将查询发送到 mysql 服务器之前陷入查询?
2 回答
根据您使用的内容,有四种方法可以完成此操作,最后一种更可靠。
一般查询日志
MySQL 提供了一种机制mysqld
,可以通过通用查询日志记录进程正在执行的所有操作。正如您在问题中所述,您可能没有持久连接,因此您需要:
mysqld
在进程启动时启用 MySQL 通用查询日志,使用--log[=file_name]
- 使用 设置全局/会话变量
SET GLOBAL general_log = 'ON'
。
- 使用 设置全局/会话变量
有关通用查询日志的更多信息,请参阅MySQL 5.1 参考手册。
使用sed
(或手动!)
该技术涉及创建一个新函数,并重命名所有mysqli_*
函数调用以调用另一个函数。
假设您新创建的函数名为proxy_query()
,您可以使用sed
它遍历所有文件并自动更改它们:
sed i '.bck' 's/mysqli_query/proxy_query/'
参数指定文件应在-i
适当位置进行编辑,并且应从原始文件制作副本并.bck
附加扩展名。
扩展runkit
名
我必须承认我在这里很天真,而且我之前没有使用过这个特定的扩展 - 但是可以使用这个 PECL 扩展重命名函数。可以在此处找到此扩展的要求,并注意它不与 PHP 捆绑在一起。
与上面一样,您可以创建一个代理函数,所有调用都将通过。假设它也被称为proxy_query
. 用法会是这样的:
// rename the function (a very bad idea, really!)
runkit_function_renam('mysqli_connect', 'proxy_super');
function mysqli_query($query, $resultmode = MYSQLI_STORE_RESULT)
{
// do something with the SQL in $query
// .. and call mysqli_query, now proxy_super
return proxy_super($query, $resultmode);
}
我必须在这里指出,这种方法是非常不鼓励的。您永远不需要设置默认的 PHP 函数。
使用 Pdo/OO-mysqli
这是最简单的技术,也可能是最可靠的技术。如果您已经在使用 Pdo,则可以简单地扩展\Pdo
该类。MySQL 改进()可以使用类似的方法mysqli
:
class MyPdo extends \Pdo
{
public function query($query [, ... ])
{
// do something with $query
return parent::query($query [, ... ]);
}
}
还要注意,这仅在您使用 Pdo 时才有效,并且如果您能够更改Pdo
对象的实例化,以将其覆盖到您自己的类:MyPdo
. 有关\Pdo
班级及其孩子的更多信息,请参阅手册。
如果您想使用 SQL 探查器监视传入的查询,这可能是一种很好的方式来收集有关 SQL 内部正在发生的事情的信息,而无需通过单个函数或过程将其全部传递。