gpt4 book ai didi

php - 关于mysql转PDO的问题

转载 作者:搜寻专家 更新时间:2023-10-31 20:55:40 25 4
gpt4 key购买 nike

我最近决定将我当前使用 php mysql_query 执行的所有普通 mysql 查询切换为 PDO 样式查询,以提高性能、可移植性和安全性。对于这个数据库交互工具的任何专家,我只是有一些快速的问题

  1. 如果所有的statements都准备好,是否可以防止注入(inject)? (我在 php.net 上注意到它写了'但是,如果查询的其他部分是用未转义的输入构建的,SQL 注入(inject)仍然是可能的'我不太确定这是什么意思)。这是否仅仅意味着如果所有变量都通过 prepare 函数运行它是安全的,而如果直接插入一些则不是?

  2. 目前,我在页面顶部有一个连接,并在页面的其余部分执行查询。我更详细地查看了 PDO,并注意到每个涉及连接和连接关闭的查询都有一个 try and catch 过程。有没有一种直接的方法来连接然后重用该连接,而不必尝试一切或通过连接、查询和关闭不断重复该过程?

  3. 谁能用通俗易懂的语言简要解释一下 set_exception_handler 的用途?

我感谢任何更有经验的人的任何建议。

最佳答案

  1. 没有防止 SQL 注入(inject)的 Elixir 。即使您已准备好,也可能会有不安全的查询。

    $sql = "SELECT * FROM MyTable WHERE id = " . $_GET["id"];
    $stmt = $pdo->prepare($sql);

    看到了吗? Prepare 只需要一个字符串并将其准备为 SQL 查询。您仍然可以在准备字符串之前将不安全的内容插入到字符串中。。 prepare 只看到一个字符串,它不知道你是按字面意思写的,还是部分字符串来自不可信的来源。

    您可以在 SQL 查询中使用参数占位符,然后当您对准备好的语句调用 execute() 时,您可以提供动态值。但是您只能使用参数占位符来代替 SQL 表达式中的文字值——不能对查询中的其他类型的动态内容进行参数化。看我的介绍SQL Injection Myths and Fallacies有关 SQL 注入(inject)的示例和许多其他信息。

  2. 我不会将每个 PDO 调用都放在try block 中。我编写了一个类来为我的应用程序的某些逻辑内聚部分封装数据访问。当我调用那个类时,我将调用包装在一个 try block 中。如果该类中潜在的许多数据库访问操作之一出现问题,我会发现并处理它。

  3. 您可以使用 set_exception_handler() 代替 catch block 。如果您的应用程序中发生异常,但您没有捕捉到它,并且它一直在堆栈中向上冒泡,直到它中止脚本,调用此函数。想象一下您的整个 PHP 脚本都在一个顶级 try block 中,并且您声明的代码将进入相应的 catch block 。

    我从不使用 set_exception_handler()。函数运行后,您的脚本无论如何都会停止执行,因此没有机会重试产生异常的操作。它还在顶级范围内运行,因此您失去了异常的上下文。此时您唯一可以做的就是漂亮地打印异常消息并退出。我更喜欢在离异常更近的地方处理异常,这样我就可以添加一些关于异常上下文的信息,或者在 PHP 脚本停止之前做一些其他事情。


回复你的评论:

您不应该对表名或列名使用 mysql_real_escape_string(),因为引用标识符的规则不同于引用文字字符串值的规则。只是不要将来自外部或不受信任来源的输入插入到您的 SQL 查询中。

我在演示文稿中使用关联数组编写了一个代码示例,这样如果用户输入与已知值匹配,它会将其用作关联数组中的键来查找表(或列,在我的例子)。这意味着您不必使用任何转义/引用函数,因为您不会将不受信任的内容插入到您的 SQL 查询中。您只能插入您在关联数组中预定义的值。

关于异常,我的意思是(在高层次上):

$domainObject = new MyDomain();

try {
$domainObject->create_report($formInput);
} catch (PDOException $e) {
// Report error politely so the user knows what happened
// and what they can do to fix it.
}

create_report() 内部的工作很复杂,可能涉及多个 SQL 查询,其中任何一个都可能以多种方式出错。您不一定需要为该函数内的每个 SQL 操作捕获异常,您可以只捕获从函数中弹出的任何和所有异常,并在一个地方处理它们,在调用 create_report( )

此外,您可能不想向他们逐字逐句地吐出异常消息,因为他们不知道该怎么做。

关于php - 关于mysql转PDO的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2841691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com