Php 从mysqli转换为prepared语句

Php 从mysqli转换为prepared语句,php,mysqli,prepared-statement,Php,Mysqli,Prepared Statement,我正在尝试将mysqli_*语句中的代码转换为准备好的语句,以防止SQL注入。以下代码是我正在尝试转换的代码(它目前工作正常): 以下是我尝试转换为准备好的状态。任何使这一点更加简洁的方法都将不胜感激(因为我将从2行代码扩展到多行代码): $SQL=“SELECT*FROM”.PREFIX.“问题,其中id=”?“和禁用的class='0'限制1”; $PRE=mysqli\u stmt\u init($linkDB); //如果(!$PRE=mysqli_prepare($linkDB,$SQ

我正在尝试将mysqli_*语句中的代码转换为准备好的语句,以防止SQL注入。以下代码是我正在尝试转换的代码(它目前工作正常):

以下是我尝试转换为准备好的状态。任何使这一点更加简洁的方法都将不胜感激(因为我将从2行代码扩展到多行代码):

$SQL=“SELECT*FROM”.PREFIX.“问题,其中id=”?“和禁用的class='0'限制1”;
$PRE=mysqli\u stmt\u init($linkDB);
//如果(!$PRE=mysqli_prepare($linkDB,$SQL)){(alt尝试)
如果(!mysqli_stmt_prepare($PRE$SQL)){
echo“错误:无法准备查询:“.SQL.”、“.mysqli_错误($linkDB)”;
}否则{
mysqli_stmt_bind_param($PRE,“i”,$test);
$test=$_POST['article'];
如果(!mysqli_stmt_execute($PRE)){
echo“错误:无法执行查询:“.SQL.”、“.mysqli_错误($linkDB)”;
}否则{
$details=mysqli\u stmt\u get\u result($PRE);
$detail=mysqli\u fetch\u assoc($details);
mysqli_stmt_close($PRE);
}
}

上面的代码没有在$detail变量中返回/存储db值,以便以后在脚本中进行处理。我已经尝试注释mysqli_stmt_close($PRE)如果你不是一个有经验的程序员,我会推荐PDO。它是面向对象的,适合现代的PHP编码方式

在配置文件中,您将:

$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
还有你的剧本:

$statement = $pdo->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id = :id AND disabled = 0 LIMIT 1';
$statement->execute(['id' => $_POST['article']);
$result = $statement->fetch(PDO::FETCH_ASSOC);

如果你不是一个有经验的程序员,我会推荐PDO。它是面向对象的,适合现代的PHP编码方式

在配置文件中,您将:

$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
还有你的剧本:

$statement = $pdo->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id = :id AND disabled = 0 LIMIT 1';
$statement->execute(['id' => $_POST['article']);
$result = $statement->fetch(PDO::FETCH_ASSOC);

代码中的主要错误是在查询中键入了
“?”
。如果
在引号内,则不会将其视为占位符,而是视为文字值

在使用MySQLi时,您应该这样做。如果这样做,那么就不再需要检查每个函数的结果。您还应该使用OOP样式,因为它不太冗长,而且您不太可能犯愚蠢的错误

// put this line before you open the MySQLi connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$stmt = $linkDB->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id=? AND disabled=0 LIMIT 1');
$stmt->bind_param('i', $_POST['article']);
$stmt->execute();
$detail = $stmt->get_result()->fetch_assoc();

代码中的主要错误是在查询中键入了
“?”
。如果
在引号内,则不会将其视为占位符,而是视为文字值

在使用MySQLi时,您应该这样做。如果这样做,那么就不再需要检查每个函数的结果。您还应该使用OOP样式,因为它不太冗长,而且您不太可能犯愚蠢的错误

// put this line before you open the MySQLi connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$stmt = $linkDB->prepare('SELECT * FROM '.PREFIX.'Issues WHERE id=? AND disabled=0 LIMIT 1');
$stmt->bind_param('i', $_POST['article']);
$stmt->execute();
$detail = $stmt->get_result()->fetch_assoc();

感谢您的回复。不幸的是,项目的其他部分正在使用过程调用,而不是面向对象的风格。我不想重新编写所有这些,我只想现在就更新到准备好的语句。如果有任何帮助,我们将不胜感激!我只想指出我为那些使用PD的人找到的另一个链接O感谢您的回复。不幸的是,项目的其他部分正在使用过程调用,而不是面向对象的风格。我不想重新编写所有这些,我只想现在就更新到准备好的语句。如果有任何帮助,我们将不胜感激!我只想指出我为那些使用PDO我检查了引用的链接,但它说不要检查诸如“if($result)”之类的错误。如果我不检查这些并通过电子邮件报告,开发人员如何知道问题是什么?如果php只是吐出错误,那么这将显示给用户,使网站看起来不专业,我们的开发人员对问题是什么一无所知。这只是围绕?的引用,感谢提示!等待进一步澄清对于上面的问题,我不是还要做一个“如果($result)”来抓住它吗?达曼,@user1646428你们都犯了一个大错误。PHP不会“吐”任何东西。它完全按照程序员的要求执行。要在屏幕上显示它吗?好的,PHP会在屏幕上显示它。要记录它吗?没问题,它会被记录。要通过电子邮件发送吗?相同。要向用户显示自定义错误页吗?关键是:只需告诉PHP这样做。在一个地方显示一次。然后根据需要进行更改。而catc替换错误只会使代码膨胀,并使错误报告变得不灵活。检查@YourCommonSense是的,你是对的,也许我误解了OP在这里想要什么…我检查了引用的链接,但它说不要检查错误,如“if($result)”。如果我不检查这些并通过电子邮件报告,开发人员如何知道问题是什么?如果php只是吐出错误,那么这将显示给用户,使网站看起来不专业,我们的开发人员对问题是什么一无所知。这只是围绕?的引用,感谢提示!等待进一步澄清对于上面的问题,我不是还要做一个“如果($result)”来抓住它吗?达曼,@user1646428你们都犯了一个大错误。PHP不会“吐”任何东西。它完全按照程序员的要求执行。要在屏幕上显示它吗?好的,PHP会在屏幕上显示它。要记录它吗?没问题,它会被记录。要通过电子邮件发送吗?相同。要向用户显示自定义错误页吗?关键是:只需告诉PHP这样做。在一个地方显示一次。然后根据需要进行更改。而catc如果出现错误,你的代码就会膨胀,错误报告会变得死板。检查@YourCommonSense是的,你是对的,也许我误解了OP的意思。。。