PHP PDO - 使用绑定值更新(设置和参数相同)


PHP PDO - Update with bindValue (set and where parametes are same)

这对我来说有点混乱,所以我会尽力解释它。

我正在运行更新,但没有任何反应。

这是我得到的查询:

"UPDATE users SET name = :name, surname = :surname WHERE name = :name AND surname = :surname"

我像这样开始查询:

$data = ['name' => 'Sasha', 'surname' => 'M'];
$user = $users->where(['name' => 'TestName', 'surname' => 'TestSurname'])->update($data);

这是更新功能:

public function update($data)
    {
        $fields = explode(',', $this->prepareFields($data));
        $values = explode(',', $this->prepareValues($data));
        $i = 0;
        $count = count($fields);
        $query = "UPDATE {$this->_tablename} SET ";
        for($i; $i < $count; $i++):
            $query .= $fields[$i] . " = " . $values[$i] . ',';
        endfor;
        $query = rtrim($query, ',');
        $query .= " WHERE " . rtrim($this->_dbWhere, ' AND ');
        $this->query($query);
        $this->bindData($data);
        $this->_dbBind = call_user_func_array('array_merge', $this->_dbBind);
        $this->bindData($this->_dbBind);
        $this->execute();
        return $this->lastInsertId();
    }

其中功能:

public function where($field, $value = null)
    {
        if(!is_array($field)):
            $this->_dbWhere  .= $field . ' = :' . $field . ' AND ';
            $this->_dbBind[] = [$field => $value];
        else:
           foreach($field as $key => $value):
               $this->_dbWhere .= $key . ' = :' . $key . ' AND ';
                $this->_dbBind[] = [$key => $value];
           endforeach;
        endif;
        return $this;
    }

绑定数据功能:

public function bindData($data)
    {
        foreach ($data as $key => $value) :
            $this->bind(':' . $key, $value);
        endforeach;
    }

公共函数 bind($param, $value, $type = null){

    if (is_null($type)) {
        switch (true) {
            case is_int($value):
                $type = 'PDO::PARAM_INT;
                break;
            case is_bool($value):
                $type = 'PDO::PARAM_BOOL;
                break;
            case is_null($value):
                $type = 'PDO::PARAM_NULL;
                break;
            default:
                $type = 'PDO::PARAM_STR;
        }
    }
    $this->stmt->bindValue($param, $value, $type);
}
准备

字段和准备值:

public function prepareFields($data)
    {
        return $fields = implode(', ', array_keys($data));
    }
    public function prepareValues($data)
    {
        $values = implode(', :', array_keys($data));
        return ':' . $values;
    }

查询功能:

public function query($query){
        $this->stmt = $this->handler->prepare($query);
    }

关键在于您在 WHERE 子句和语句的 SET 部分中使用相同的占位符:fieldname。您确实需要更正此处提出的其他小问题,但一个简单的解决方案是在 where() 函数中进行此更改:

    if(!is_array($field)):
        // make up a placeholder name distinct from the one used in SET clause
        $field_placeholder = ":where_".$field
        $this->_dbWhere  .= $field . ' = ' . $field_placeholder . ' AND ';
        $this->_dbBind[] = [$field_placeholder => $value];
    else: