如何在PHP PDO中执行算术运算?

时间:2016-11-30 16:32:23

标签: php mysql pdo

问题有点简单(可能有点傻),但我会给你一个例子 在我正在研究的项目中,我创建了一些函数(类方法),它们将为我执行一些基本的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的网站,用户拥有属性点,具有特殊效果的项目等。
所有这些用户属性和项目效果都由管理员创建或操作。

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

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

管理员用户可以通过一个简单的控制面板选择他们想要的项目效果,JSON将根据它自动生成。

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

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

答案是:

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

我知道这听起来很混乱,甚至可能是错误的,所以我完全乐于接受更好的建议。 对不起有误,我希望你们能在这里帮助我 此致!

1 个答案:

答案 0 :(得分:0)

绑定是针对字段设计的,而不是名称。您正在寻找的是可以更改的白色字段列表。

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

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

以下是发生的事情:

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