PHP 使用 Mysqli 的 prepare 语句有啥好处?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 使用 Mysqli 的 prepare 语句有啥好处?相关的知识,希望对你有一定的参考价值。

好处:
(1)解析查询只有一次
(2)执行一些查询优化步骤只有一次
(3)通过二进制协议发送参数比送他们为ASCII文本更有效
比如DATE,对于准备之后,发送日期只用3个字节;如果没有准备,日期必须以字符串的形式发送,需要数据库方再解析,这样需要发送10个字节。
(4)只有参数(不是整个查询文本)需要为每个执行要发送
(5)的mysql直接存储parameteres到服务器上的缓冲区
(6)安全性也有帮助,就没有必要逃避或引用值。

坏处:
(1)本地到一个连接,以便另一个连接不能再使用
(2)不能使用MySQL查询缓存(5.1版本之前)
(3)不总是更有效,如果你使用它只有一次
(4)存储函数中不能使用(存储过程是可以的)
(5)有可能会导致“泄漏”如果你忘记释放它
参考技术A

这是php官网的解释:

 

Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
PDO will emulate prepared statements/bound parameters for drivers that do not natively support them, and can also rewrite named or question mark style parameter markers to something more appropriate, if the driver supports one style but not the other.


大致意思是说有两个好处:

    可以通过驱动让服务端缓存查询计划,从而提高查询效率;

    可以防止SQL注入,自动转义一些特殊字符.

参考技术B mysql是非持继连接函数而mysqli是永远连接函数。

也就是说mysql每次链接都会打开一个连接的进程而mysqli多次运行mysqli将使用同一连接进程,从而减少了服务器的开销

如何在使用 mysqli prepare 时获取 assoc 数组

【中文标题】如何在使用 mysqli prepare 时获取 assoc 数组【英文标题】:How to fetch assoc array while using mysqli prepare 【发布时间】:2013-09-12 08:58:44 【问题描述】:

为了确保我的数据库安全,我使用了准备语句。这是我的代码:

//connecting to MySql database
$con=mysqli_connect("host","user","pass","dbname");
// checking database connection
if (mysqli_connect_errno($con))
    echo "Failed to connect to MySQL: " . mysqli_connect_error();


$stmt = mysqli_prepare($con,"SELECT * FROM `table` WHERE emb=? LIMIT 1");
mysqli_stmt_bind_param($stmt, 's', $emb);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);

现在我想知道如何使用 ASSOC 获取数组

$embInfo = mysqli_fetch_array($stmt, MYSQLI_ASSOC);

我想要这个,这样我就可以在下面放一些东西来获取值

$embInfo['name']

$embInfo['email']

【问题讨论】:

我想这会有所帮助 ***.com/questions/15846583/… 并且更好地转向 PDO 如果 mysqlnd 不可用,则需要定义所有字段并使用 bind_result 或 use something like this to dynamically define the fields. 如果我使用mysqli-stmt.get-result 会怎样?这会有帮助吗?有人在 *** 聊天中提出了这个建议。 【参考方案1】:

试试这个:

//connecting to MySql database
$con=mysqli_connect("host","user","pass","dbname");
// checking database connection
if (mysqli_connect_errno($con))
    echo "Failed to connect to MySQL: " . mysqli_connect_error();


$stmt = mysqli_prepare($con,"SELECT * FROM `table` WHERE emb=? LIMIT 1");
mysqli_stmt_bind_param($stmt, 's', $emb);
mysqli_stmt_execute($stmt);


while($embInfo = mysqli_fetch_array($stmt, MYSQLI_ASSOC))
  echo 'My name is '.$embInfo['name'].'and my email is '.$embInfo['email'].'<br/>';



mysqli_stmt_close($stmt);

【讨论】:

“试试这个”——有什么用?【参考方案2】:

我可以建议一个替代方案


  $server = '';
  $user = '';
  $pass = '';
  $db = '';

  // connect to the database
  $mysqli = new mysqli($server, $user, $pass, $db);

  // show errors (remove this line if on a live site)
  mysqli_report(MYSQLI_REPORT_ERROR);

  $club=$_POST'club'];
  $sql = "SELECT * FROM players WHERE club = '$club'";
  $result=mysqli_query($mysqli,$sql);
  while($row = mysqli_fetch_array($result))
  
    echo $row['player'];
  
  

【讨论】:

但我认为这并不安全。 SQL 注入可以通过此代码破坏数据库。这就是我尝试使用准备好的语句的原因。 $club = mysql_real_escape_string($_POST['club']);试试这个 @sushruth-sv 真正的转义字符串已过时,您建议使用已弃用的 mysql。我不明白你想说什么。你应该知道这些天是最安全的方法。 更加安全和快速,因为 MySQL 引擎能够为连续查询重用它的旧执行计划

以上是关于PHP 使用 Mysqli 的 prepare 语句有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章

调用“mysqli_stmt_prepare”时是不是应该手动检查错误? [复制]

我的 php/mysqli 中出现错误和警告 [重复]

具有多个连接的 mysqli Prepared 语句不断返回 false [关闭]

为啥 MySQLi 库本身不支持命名参数?

如何使用 mysqli->prepare 执行更新?

php? PDO 或 mySQLi [重复]