【问题标题】:converting raw queries to prepared statement将原始查询转换为准备好的语句
【发布时间】:2011-12-14 05:14:44
【问题描述】:
假设我有我 1995 年的时尚功能,旨在向 mysql 发送查询。
我的项目有很多查询,我正在寻找一个能够解析原始查询的函数/类(假设:SELECT foo from bar where Pizza = 'hot' LIMIT 1)
并用 php 创建一个准备好的语句。你有什么建议吗?
这值得么?还是重写所有查询更好?
我可以在我的项目中统计 424 个查询,而这只是 SELECTs
感谢您的帮助
【问题讨论】:
标签:
php
mysql
prepared-statement
【解决方案1】:
试试这个:
function prepare1995Sql_EXAMPLE ($sqlString) {
# regex pattern
$patterns = array();
$patterns[0] = '/\'.*?\'/';
# best to use question marks for an easy example
$replacements = array();
$replacements[0] = '?';
# perform replace
$preparedSqlString = preg_replace($patterns, $replacements, $sqlString);
# grab parameter values
$pregMatchAllReturnValueHolder = preg_match_all($patterns[0], $sqlString, $grabbedParameterValues);
$parameterValues = $grabbedParameterValues[0];
# prepare command:
echo('$stmt = $pdo->prepare("' . $preparedSqlString . '");');
echo("\n");
# binding of parameters
$bindValueCtr = 1;
foreach($parameterValues as $key => $value) {
echo('$stmt->bindParam(' . $bindValueCtr . ", " . $value . ");");
echo("\n");
$bindValueCtr++;
}
# if you want to add the execute part, simply:
echo('$stmt->execute();');
}
# TEST!
$sqlString = "SELECT foo FROM bar WHERE name = 'foobar' or nickname = 'fbar'";
prepare1995Sql_EXAMPLE ($sqlString);
示例输出为:
$stmt = $pdo->prepare("SELECT foo FROM bar WHERE name = ? or nickname = ?");
$stmt->bindParam(1, 'foobar');
$stmt->bindParam(2, 'fbar');
$stmt->execute();
如果您的所有 sql 语句都与示例相似,这可能会起作用,条件是字符串。但是,一旦您需要等同于整数,就必须更改模式。这就是我现在能做的。我知道这根本不是最好的方法,但为了一个样本,试一试:)
【解决方案2】:
我建议对这些查询进行正则表达式搜索(我认为它们应该有模式),然后对它们进行排序,看看哪些相似/可以分组。
此外,如果您有某种日志,请检查哪些日志执行得最频繁,将稀有查询移至准备好的语句没有多大意义。
【解决方案3】:
老实说,您应该重写您的查询。使用正则表达式会起作用,但您可能会发现某些查询无法由模式处理。问题是查询有很多复杂性,只需要一种模式来解析它们。此外,最好的做法是让您的代码简单地完成工作并重写您的查询。
祝你好运!
【解决方案4】:
您可能希望启用跟踪工具并在 SQL 命令发送到数据库时对其进行捕获。预先警告,你即将看到的东西会吓到你:)