【问题标题】:How can I perform arithmetic operations in PHP PDO?如何在 PHP PDO 中执行算术运算?
【发布时间】:2017-04-15 01:51:55
【问题描述】:

这个问题有点简单(可能有点傻),但我会给你一个例子。
在我正在进行的项目中,我创建了一些函数(类方法),它们将为我执行一些基本的 SQL 操作。我需要做的就是提供诸如表名、列和值之类的信息作为参数,剩下的就交给它了。

函数结构基本上是这样的:

public function update_order($order_id, $order_value) {    
    $example_sth = $pdo->prepare("UPDATE example SET example_order = :order_value WHERE example_id = :order_id");
    $example_sth->bindParam(":order_id", $order_id);  
    $example_sth->bindParam(":order_value", $order_value);  
    $example_sth->execute();

    $data = $example_sth->fetch();
    return $data;
}

也就是说,现在假设我要执行这样的查询:

UPDATE example SET example_order = example_order + 1;

由于我使用PDO执行SQL操作,是否可以在PDO的bindParam()函数中传递“example_order + 1”部分,或者唯一的解决方案是完全删除PDO变量并直接编写算术运算在查询中?

提前感谢您的帮助。

更新

为了简单起见,我没有在问题中包含其他信息。由于提出了一些混淆,我将在此处包含这些内容,以供那些试图了解我对所有这些意图的人使用。

我做的项目是一个类似RPG的网站,用户有属性点,物品有特效等等。
所有这些用户属性和物品效果都是由管理员创建或操作的。

由于这些物品效果的作用有很大差异(它可以简单地为用户提供更多属性点,但它也可以执行更复杂的操作,例如创建或删除整个配置文件),我来的唯一解决方案to是将这些效果转化为SQL操作。
为了避免安全漏洞,我当然不会允许管理员用户创建项目来为自己保存这些 SQL 操作,所以我决定做的是保存简单的 JSON 命令,例如:

{"update":[
    {"columns":"order_id, order_value",
    "values":"16281738, 16"}
]}

管理员用户可以通过一个简单的控制面板选择他们想要的项目效果做什么,并且 JSON 将基于此自动生成。

在普通用户执行效果时,所有这些 JSON 命令都必须传递给负责 SQL 操作的类方法(我上面提到的那些)。

现在有人问我:为什么我必须保存算术运算?

答案是:

如果这些物品效果之一是专门为用户创建的,我知道我可以在创建物品效果之前简单地自己执行计算,因此 JSON 命令已经包含最终结果(例如,“”列“ : "life_ponts", "value", "77"")。
但由于这些操作/项目效果并非专门针对用户,它们必须是主观的(即,基于当前执行它们的用户的工作)。
因此,我现在唯一的解决方案是不保存最终结果(因为在这种情况下这是不可能的),而是保存必须对这些属性点进行的算术运算。
所以,当我保存 ""column": "life_points", "value": "life_points + 1"" 时,我想做的是从执行命令的用户那里获取 life_points,并增加它1.

我知道这听起来令人困惑,甚至可能是错误的,所以我完全愿意接受更好的建议。 很抱歉造成了误会,希望大家能帮帮我。
问候!

【问题讨论】:

  • 为什么需要绑定它?绑定参数的目的是防止 SQL 注入,即用户在您的查询中注入 SQL 代码。如果您只想将值加一,则可以执行您拥有的查询。没有用户输入。
  • 是的,我知道,@AurelBílý。但是我创建的类方法应该作为与该表相关的所有 UPDATE 操作的标准,因此它应该接受各种信息(包括用户输入或问题中提到的简单算术运算)。当我要做一件事或另一件事时,它变化很大,所以我不想因为查询不合适而需要更改方法。
  • 用户如何发送算术运算?输入会是什么样子?那么此脚本是否会始终更新相同的字段,或者更新的字段取决于用户输入?
  • 在询问的查询中,example_order 是用户传递的值吗?如果是这样,您可以通过简单的算术运算增加它然后插入它,而不是在查询中进行......
  • 使用 ORM 解决这个问题会容易得多(例如,参见 Doctrine)。您将更新对象的属性,ORM 将处理数据库中的必要更新。这样你就不必重新发明轮子了;)整个社区已经成功地完成了这项工作

标签: php mysql pdo


【解决方案1】:

绑定是为字段 value 而设计的,而不是名称。您正在寻找的是可以更改的字段白名单。

如果你想更进一步,我建议你这样做:

{
    "update": [
        {
            "column": "order_id",
            "type": "relative|absolute",
            "value": 16281738
        }
    ]
}

这是发生了什么:

  1. 您设置了每列的操作,而不是一组。您应该使用白名单
  2. 添加了一个新字段 - “type”。它只能采用两个值:relativeabsolute,它们指定要执行的操作类型。如果它有任何其他值,则存在风险,您应该丢弃或抛出异常。
  3. 该值为整数/浮点数。当您 json_decode 时,您应该将其转换为 int/float 或检查 if (is_numeric())。这很重要,因为您可以安全地将 int/float 替换为 sql 查询,而不会有注入风险。

最后您说有时您需要复杂的操作 - 使用 type 字段来指定它。但是,如果您不需要其他值,请考虑改用布尔值

【讨论】:

    猜你喜欢
    • 2013-04-16
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2013-05-16
    • 1970-01-01
    • 2017-11-19
    相关资源
    最近更新 更多