M M*_*ler 5 php mysql mysqli mysql-real-escape-string prepared-statement
好吧,我还是不太懂.我一直在阅读,为了正确地逃避你的MySQL查询,你需要使用mysqli_prepare()和mysqli_bind_param().
我尝试使用这个设置,坦率地说,它有点笨拙.当我不需要再次引用变量时,我会通过引用传递变量,并且只需要更多行代码来完成相同的任务.
我想我只是不知道它们之间的区别:
<?php
$sql = new \MySQLi(...);
$result = $sql->query('
UPDATE `table`
SET
`field` = "'.$sql->real_escape_string($_REQUEST[$field]).'";
');
?>
Run Code Online (Sandbox Code Playgroud)
和
<?php
$sql = new \MySQLi(...);
$stmt = $sql->prepare('
UPDATE `table`
SET
`field` = ?;
');
$value = $_REQUEST[$field];
$stmt->bind_param('s', $value);
$stmt->execute();
$result = $stmt->get_result();
unset($value);
?>
Run Code Online (Sandbox Code Playgroud)
除了更多的代码.
我的意思是,他们是否实现了这一点,以便人们在发送查询之前不会忘记转义值?还是以某种方式更快?
或者当我打算重复使用相同的查询时(因为mysqli_stmt可以重复使用)并在其他情况下使用传统方法,我应该使用此方法吗?
您正在阅读的内容,即您需要使用mysqli_prepare()和mysqli_bind_param()函数“正确转义 MySQL 查询”的内容是错误的。
确实,如果您使用mysqli_prepare()and mysqli_bind_param(),则不需要(也不应该)“转义”作为绑定参数提供的值。所以,从这个意义上说,你所读到的内容有一定道理。
仅当 SQL 文本(查询的实际文本)中包含不安全变量时,您才需要“正确转义”变量,通常是通过将变量包装在mysqli_real_escape_string()函数调用中。
(我们注意到,可以利用准备好的语句,并且仍然在 SQL 文本中包含未转义的变量,而不是将变量值作为 bind_parameters 传递。这确实违背了使用准备好的语句的目的,但重点是,无论哪种方式,您都可能编写容易受到攻击的代码。
MySQL 现在支持“服务器端”准备好的语句(如果在连接中启用了该选项),这是重复执行相同 SQL 文本的性能优化(在某些情况下)。(其他数据库(例如 Oracle)长期以来一直支持这一点,在 Oracle 中,使用准备好的语句一直是一种熟悉的模式,就像永远一样。)
问:他们是否实现了[准备好的语句],以便人们在查询中发送值之前不会忘记转义值?
答:根据不使用准备好的语句时易受 SQL 注入攻击的代码示例的数量,尽管有有关mysql_real_escape_string()函数的文档,您仍然认为这肯定是充分的理由。
我认为一个很大的好处是,当我们阅读代码时,我们可以将 SQL 语句视为单个字符串文字,而不是一堆变量的串联,带有引号和点以及对 mysql_real_escape_string 的调用,这不是太对于简单的查询来说不好,但是对于更复杂的查询,它就过于麻烦了。占位符的使用?使得 SQL 语句更容易理解,...确实,我需要查看其他代码行以找出其中填充的值。(我认为 Oracle 风格的命名参数:fee, :fi, :fo, :fum比位置?, ?, ?, ?表示法更可取。)但是拥有 STATIC SQL 文本才是真正的好处。
问:或者说速度更快?
正如我之前提到的,使用服务器端准备好的语句可以在性能方面具有优势。它并不总是更快,但对于重复执行同一语句,唯一的区别是文字值(如重复插入),它可以提供性能提升。
问:或者当我打算重复使用相同的查询(因为mysqli_stmt可以重复使用)时我应该使用这种方法,而在其他情况下使用传统方法?
这取决于你。我更喜欢使用静态 SQL 文本。但这确实来自于使用 Oracle 的悠久历史,并且在 MySQL 中使用相同的模式很自然。(尽管如此,Perl 使用 DBI 接口,Java 使用 JDBC 和 MyBATIS,或其他 ORM(Hibernate、Glassfish JPA 等)
在 PHP 中遵循相同的模式感觉很自然;mysqli_ 和 PDO 的引入是对晦涩(且被滥用)的 mysql_ 接口的一种令人欢迎的缓解。
遵循任一模式都可以编写出好的代码。但我挑战你提前考虑一下更复杂的 SQL 语句,以及选择使用mysqli_real_escape_string()和连接要执行的动态字符串(而不是使用静态 SQL 文本和绑定参数)是否可以读取和破译实际的 SQL对于发现自己维护着不是自己编写的代码的灵魂来说,执行起来更加复杂。
我认为研究表明,代码的读取次数是编写次数的十倍,这就是为什么我们努力生成可读、可理解的代码,即使这意味着更多的代码行。(当每个语句都在做一件可识别的事情时,这通常比在一个复杂的语句中阅读一堆串联的函数调用更容易理解。
| 归档时间: |
|
| 查看次数: |
5361 次 |
| 最近记录: |