Php 我可以在SQL查询中使用htmlentities()吗?

Php 我可以在SQL查询中使用htmlentities()吗?,php,sql,html-entities,Php,Sql,Html Entities,非常感谢我的原始问题引发的讨论。我接受了Jay的建议,使用bind_param(),但我不明白这可能会导致服务器错误:“网站在检索时遇到错误…”。我不知道示例附带的参数“sssd”是什么意思 任何关于服务器错误产生原因的建议都将不胜感激 <?php $mysqli = new mysqli('my-database-address', 'my-username', 'my-password', 'my-database-name'); f (mysqli_connect_errno())

非常感谢我的原始问题引发的讨论。我接受了Jay的建议,使用bind_param(),但我不明白这可能会导致服务器错误:“网站在检索时遇到错误…”。我不知道示例附带的参数“sssd”是什么意思

任何关于服务器错误产生原因的建议都将不胜感激

<?php

$mysqli = new mysqli('my-database-address', 'my-username', 'my-password', 'my-database-name');
f (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit(); }

$stmt = $mysqli->prepare("INSERT INTO volunteers VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param('sssd', $first_name, $last_name, $street_address, $apt_unit, $city, $zip, 
$email, $phone, $planning, $signatures, $canvassing, $phone_bank, $media, $press_releases,
$volunteer_coordinator, $speaker, $house_parties, $web_page, $other, $skills, $organizations);

$first_name = '$_POST[first_name]'; $last_name = '$_POST[last_name]'; $street_address = '$_POST[street_address]';
$apt_unit = '$_POST[apt_unit]'; $city = '$_POST[city]'; $zip = '$_POST[zip]'; $email = '$_POST[email]';
$phone = '$_POST[phone]'; $planning = '$_POST[planning]'; $signatures = '$_POST[signatures]'; 
$canvassing = '$_POST[canvassing]'; $phone_bank = '$_POST[phone_bank]'; $media = '$_POST[media]'; 
$press_releases = '$_POST[press_releases]'; $volunteer_coordinator = '$_POST[volunteer_coordinator]'; 
$speaker = '$_POST[speaker]'; $house_parties = '$_POST[house_parties]'; $web_page = '$_POST[web_page]'; 
$other = '$_POST[other]'; $skills = '$_POST[skills]'; $organizations = '$_POST[organizations]';

$stmt->execute();
$stmt->close();

echo "<br /><br />";
echo "<div class='center-col-wrap'>";
echo "Your information has been received.";
echo "<br /><br />";
echo "Thank you for volunteering!"; echo "<br />";
echo "Your help in this effort to bring greater democracy to Oakland"; echo "<br />";
echo "will go a long way to create a healthy and informed community."; echo "<br />";
echo "<br /><br />";
echo "<a href='http://communitydemocracyproject.org/'>Return to CDP Home Page.</a>";
echo "</div>";

$mysqli->close();
?>
$sql="INSERT INTO volunteers (first_name, last_name, street_address, apt_unit, city, zip, email, phone,
planning, signatures, canvassing, phone_bank, media, press_releases, volunteer_coordinator, speaker, 
house_parties, web_page, other, skills, organizations)
VALUES
('htmlentities($_POST[first_name])','htmlentities($_POST[last_name])','htmlentities($_POST[street_address])',
'htmlentities($_POST[apt_unit])','htmlentities($_POST[city])','htmlentities($_POST[zip])',
'htmlentities($_POST[email])','htmlentities($_POST[phone])','$_POST[planning]','$_POST[signatures]','$_POST[canvassing]','$_POST[phone_bank]',
'$_POST[media]','$_POST[press_releases]','$_POST[volunteer_coordinator]','$_POST[speaker]',
'$_POST[house_parties]','$_POST[web_page]','$_POST[other]','htmlentities($_POST[skills])','htmlentities($_POST[organizations])')";
从来都不想对要插入数据库的数据使用
htmlentities()

从未! 仅在将数据输出到网页时使用它


否则,如果你想用这些数据做任何事情,而不是直接到web浏览器(思考、发送电子邮件、计算字数或输出到CSV,你有什么),你会很快意识到你的错误。

要想准确地回答你的问题,你需要退出你的字符串:

$sql="INSERT INTO volunteers (...) VALUES    
('".htmlentities($_POST['first_name'])."','".htmlentities($_POST['last_name'])'." ...
(但是,正如西奥多清楚地说的,请不要这样做。这很糟糕。真的,请不要这样做。请!)

我认为你在试图逃避你的输入/输出。最好的方法是首先停止SQL注入,使用您最喜欢的DB转义方法。我只是以此为例,您可能有一个比以下简短示例代码更好的设置:

$sql="INSERT INTO volunteers (...) VALUES    
('".$mysqli->real_escape_string($_POST['first_name'])."','".$mysqli->real_escape_string($_POST['last_name'])'." ...
然后在输出时,使用htmlentities进行转义:

echo htmlentities($output->first_name);

正如西奥多所说,永远不要使用
htmlentities()
来“转义”你想放在数据库中的东西

当来自外部(用户)的任何内容存储在数据库中时,我强烈建议使用预先准备好的语句

准备好的语句非常容易使用

如果使用PDO访问数据库,则可以找到帮助。 如您所见,
bindParam()
方法用于将任何值分配给查询中的占位符

如果您使用mysqli,您可以找到文档。
bind_param()
的语法稍有不同,因为占位符没有名称(顺序很重要),第一个参数是一个字符串,用于确定参数的类型(“s”表示字符串,“i”表示整数等等)

使用事先准备好的陈述有几个积极的影响。首先,它自动屏蔽
bindParam()
/
bind_param()
方法中提供的数据,是关闭的最佳方式,它甚至通过将执行计划存储在数据库中来优化查询的性能(这有一点开销,但如果执行一个查询两次,则会得到双倍的回报)

PS:
htmlentities()
仅当您希望向用户显示一些HTML作为原始文本时才应使用(例如代码清单)

PPS:不要使用
real\u escape\u string()
来阻止SQL注入,因为它不安全()

更新 首先,为了跟进,你应该问一个新问题。人们不会阅读已经标记为已回答的问题,通过打开新的问题,你会给善良的人们一个获得奖励的机会。:)

然而,第一个参数“sssd”告诉数据库提供程序,您正在传递四个参数,其中三个是string类型,第四个是double类型(在文档中的示例中,三个字符串和一个double是绑定的(“DEU”、“Bavarian”、“F”和11.2))。这里的情况显然不是这样,实际上您正在传递(绑定)21个值

根据
表中列的类型,您需要传递21个字符的字符串作为第一个参数。
有四种可能的字符可用于确定类型:

  • i表示整数
  • d表示双精度(浮点数)
  • s代表字符串
  • b表示布尔值
您所要做的就是检查DB列的类型。您将看到数据库中的类型有不同的名称(如varchar、float等)。如果你在谷歌上搜索这些名字,你会发现它们类似于字符串、整数、双精度和布尔值。因此,您必须根据列类型(字符串)选择最佳匹配类型≆ 瓦查尔,双人≆ 浮子≆ tinytext,字符串≆ date/datetime等。pp.)并且您应该确保值(您的$POST变量)与您定义的类型实际匹配

假设您的所有列都是类似于varchar的文本类型,第一个参数将看起来像'sssss'(21倍s)或'sssssss',如果接受志愿者协调器的列是int类型(仅举个例子)

完成此操作后,您应该仔细检查
f(mysqli\u connect\u errno())
是否是与复制和粘贴相关的错误,或者您是否确实错过了代码中的
i
(应该是
if(mysqli\u connect\u errno())

如果你检查过你应该考虑写<代码> $xPr[ [XYZ ] ] />代码,而不是<代码> '$XPOST[XYZ] '/COD>,它会帮助你,真的(<代码> \代码>标记一个字符串的开始/结束,XYZ实际上是这里的字符串)。 如果仍然遇到错误,请通过添加
错误报告(E_ALL)来启用更详细的错误信息位于文件顶部(出于安全原因,当您的网站上线时,您应该删除此代码),并询问新问题

更新2 仔细检查MySQL连接字符串(在
MySQL()
方法中传递的参数)。您确定您的密码以@开头,以句号结尾吗?顺便说一下,你不应该在公共场合发布密码等

通过运行仅包含以下内容的脚本,确保您的服务器支持mysqli方法

<?php
// Show all information, defaults to INFO_ALL
phpinfo();
?>


检查输出是否有以下内容:

Clair,很高兴能提供帮助,等等,但是我们是否应该通过向患者展示如何开枪来鼓励不良行为?你的意思是直接回答?是的,我想你可能是对的。我编辑了我的答案,以便更清楚地说明这是不好的,b