Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 准备好的陈述对我来说是必要的吗?_Php_Mysql_Mysqli_Prepared Statement_Sql Injection - Fatal编程技术网

Php 准备好的陈述对我来说是必要的吗?

Php 准备好的陈述对我来说是必要的吗?,php,mysql,mysqli,prepared-statement,sql-injection,Php,Mysql,Mysqli,Prepared Statement,Sql Injection,我总是检查/限制/清除我在数据库查询中使用的用户变量 像这样: $pageid = preg_replace('/[^a-z0-9_]+/i', '', $urlpagequery); // urlpagequery comes from a GET var $sql = 'SELECT something FROM sometable WHERE pageid = "'.$pageid.'" LIMIT 1'; $stmt = $conn->query($sql); if ($st

我总是检查/限制/清除我在数据库查询中使用的用户变量

像这样:

$pageid = preg_replace('/[^a-z0-9_]+/i', '', $urlpagequery); // urlpagequery comes from a GET var

$sql = 'SELECT something FROM sometable WHERE pageid = "'.$pageid.'" LIMIT 1';

$stmt = $conn->query($sql);

if ($stmt && $stmt->num_rows > 0) {

    $row = $stmt->fetch_assoc();

    // do something with the database content

}
我看不出在这种情况下,使用预先准备好的语句或进一步的转义如何改进任何东西?注射似乎不可能,不是吗

我试着把事先准备好的陈述弄乱了。。我有点明白这一点,尽管编写哪怕是半个简单的查询也需要更多的时间和思考(SSSIissis等)

但是,由于我总是在DB交互之前清理用户输入,这似乎是不必要的


你能启发我吗?

准备好的陈述有时会更快。但从你问这个问题的方式来看,我认为你不需要它们

那么,通过使用预先准备好的语句,您可以获得多大的额外性能呢?结果可能会有所不同。在某些情况下,当需要从localhost检索大量数据时,我看到性能提高了5倍以上——在这种情况下,数据转换可能会占用大部分时间。在某些情况下,它还可能会降低性能,因为如果只执行一次查询,则需要额外的服务器往返,或者因为查询缓存不工作

更快地带给你

我看不出在这种情况下,使用预先准备好的语句或进一步的转义如何改进任何东西

你说得对,事实并非如此


另外,我否决了你的问题,因为在你提出问题之前,似乎没有什么研究。

问题是在这种情况下,你如何定义“改进”。在这种情况下,我会说它对代码的功能没有影响

那么对你来说有什么不同呢?你说这对你来说更容易,更快。可能是这样,但这只是一个培训问题。一旦你习惯了准备好的陈述,你就可以同样快地写出它们

与其他程序员的区别是什么?当你分享这段代码时,其他人将很难完全理解,因为准备好的语句是一种标准(或者在一个完美的世界中是)。因此,通过使用其他的东西,它实际上使其他人更难理解


更多地谈论这段代码毫无意义,因为事实上这并不重要,它只是一条非常简单的语句。但是想象一下,您编写了一个更大的脚本,将来更容易阅读和修改

$id = //validate int
$name = //validate string
$sometext = //validate string with special rules

$sql = 'SELECT .. FROM foo WHERE foo.id = '.$id.' AND name="'.$name.'" AND sometext LIKE "%'.$sometext.'%"';
你总是需要问自己:我是否正确地验证了我使用的所有变量?我犯了错误吗

而当你使用这样的代码时

$sql = $db->prepare('SELECT .. FROM foo WHERE foo.id = :id AND name=":name" AND sometext LIKE "%:sometext%"');
$sql->bind(array(
    ':id' => $id,
    ':name' => $name,
    ':sometext' => $sometext,
));
如果你做的每件事都是对的,就不必担心,因为PHP会帮你解决这个问题

当然,这不是一个复杂的查询,但是有多个变量应该可以证明我的观点



因此,我的最终答案是:如果你是一个完美的程序员,从不忘记或犯错误,独自工作,那么做你喜欢的。但如果你不是,我建议使用标准,因为它们存在的原因并不是您不能正确验证所有变量,而是您不需要验证。

您最好始终使用准备好的语句

正则表达式只是部分解决方案,但没有那么方便或通用。如果您的变量不符合可以用正则表达式过滤的模式,那么您就不能使用它们

所有的“SSIISIS”都是Mysqli的一个工件,IMHO不必要地混淆了它

我改用PDO:

$sql = 'SELECT something FROM sometable WHERE pageid = ? LIMIT 1';
$stmt = $conn->prepare($sql);
$stmt->execute(array($pageid));
看到了吗?不需要regexp过滤。在连接的部分之间不需要引用或分解字符串

在PDO中,传递一个变量数组很容易,这样就不必编写冗长的变量绑定代码

PDO还支持命名参数,如果您有一个值的关联数组,则命名参数非常方便:

$params = array("pageid"=>123, "user"=>"Bill");
$sql = 'SELECT something FROM sometable WHERE pageid = :pageid AND user = :user LIMIT 1';
$stmt = $conn->prepare($sql);
$stmt->execute($params);
如果启用PDO异常,则无需测试查询是否成功。您将知道它是否因为抛出异常而失败(FWIW,您也可以在Mysqli中启用异常)

您不需要测试
num_rows()
,只需将获取放入while循环即可。如果没有要提取的行,则循环立即停止。如果只有一行,那么它将循环一次迭代

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

    // do something with the database content

}

准备好的语句比过滤和字符串连接更容易、更灵活,在某些情况下确实如此。

当您不习惯使用它时(与大多数情况一样),只需要花费更多的时间和思考。这看起来不是比使用准备好的语句要多很多工作吗?只需将preg_replace('/[^valid_chars_here]+/i','$var)放在前面?。。不,对我来说,这更简单快捷。你不能总是做一个简单的preg_replace()。然后,您将使用适当的转义函数,即如果您必须存储诸如“O'Brien”之类的姓氏。这会使代码更加复杂。因此,养成简单使用预先准备好的语句的习惯要好得多,而且不必关心每一个特殊情况。Preg_replace并不是一个转义函数。当存在“就地”嵌套preg_替换以删除“坏”字符(顺便问一下,哪些是坏字符?)时,您的协议是什么还有一个是为了避免引用?你为什么要重新发明轮子?通常我的网站/页面/数据库/查询都非常小和简单。但偶尔我需要收集1000行。也许我应该使用准备好的语句,不是吗?不是:)如果是从一个大约1000行的表中进行的查询,那么这种大小就不能保证准备好的语句。是吗有速度问题吗?我不这么认为。不。看起来很快,那么你不需要担心写一份准备好的声明。:)继续。但是你知道,我想做最好的实践,也在不同规模的未来项目中。想使用Start的好习惯我看到你的观点。我从未见过name=“:name”(数组)在以前这样的查询中..我不应该使用bind_param('ssiiiss等')?问题也是这样..人们一直在告诉我:“为什么要使用prepared语句呢