【发布时间】:2019-11-05 01:39:16
【问题描述】:
这个问题是关于 PHP 中的解析,而不是如何将 MySQLi 迁移到 PDO。
我想将一些旧代码从 MySQLi 迁移到 PDO。该站点有 400 多个字符串查询语句。我想修改代码以使用准备好的语句。
即转换
$query = 'SELECT * from table where x='.$x.' and y > '.$y.' or (z<= 35 and auth like "%ed")'
$result = $conn->query($query);
到
$query = 'SELECT * from table where x = ? and y > ? or (z <= ? and auth like ?)';
$stmt = $conn->prepare($query);
$stmt->bind_param($x, $y, $35, '%ed');
$stmt->execute();
我首先解析 $query 字符串以查找“where”,然后查找“and”以分隔参数/值对等。
编辑:这是读取文件(在本例中为 .php 文件)中的行的基本代码:
$fn = fopen("myfile.php","r+");
while(!feof($fn)) {
$line = fgets($fn);
if (strpos($line, 'select'){
// add parse code here
};
}
当找到带有查询语句的行时,该行将是一个文字字符串,如下所示:
($line = ) $query = 'select * from menu where authlvl>0 and authlvl
那么,要解析的代码可能是这样的:
$where = substr($line, strpos($line, 'where') + 5);
$pair = array();
$j = 0;
$st = 0;
if (strpos(substr($where, $st), 'and', $st)) > 0){
while (($and = strpos(substr($where, $st), 'and', $st)) > 0){
$pair[$j] = trim(substr($where, $st, $and - 1));
$pair[$j+1] = trim(substr($where, $and + 4));
$st = $and;
$j++;
}
}
$ops = array(' ', '<', '>', '=');
(find operators to identify parameters and values for each pair...)
这在直觉上是没有效率的。有没有比这更好的方法来解析 $query 字符串来查找参数?请注意,字符串中可能有“order by”等,应该在找到参数后才附加。
【问题讨论】:
-
当然。我正在编写解析代码来查找所有查询语句并进行转换。我编写代码来修改文件没有问题。我正在寻找一种通过查找关键组件(例如运算符)来解析代码的基本方法。
-
你含糊其辞。在您的最后一段代码中,
$query中究竟存在什么?是PHP源代码吗?它看起来像什么? -
听起来是一个具有挑战性的项目。但让我们现实地看待这一点。能够编写一个解析器来正确解析每个语句,而手动编辑它们所需的时间更短。 400 可能听起来很多。 IT 将比人们想象的更快。这样看。如果这是一个系统,你需要从长远来看。您将深入了解系统并训练您的大脑快速解析 SQL。
-
我添加了更多细节以帮助理解具体问题。
-
susbstr/strpos 完全不足以解决这样的问题。使用一些正则表达式检测和提取,如果有的话。还想出 any 包装函数,而不是在准备/绑定/执行代码块之间涂抹参数绑定。