SQLSTATE [42000]:语法错误或访问冲突:1064 SQL语法中有错误

时间:2013-07-22 03:43:35

标签: php mysql pdo prepared-statement

我无法弄清楚我的read方法有什么问题(使用PDO的动态预处理语句)。 有人能指出我正确的方向吗?我不认为我正在使用任何保留的SQL字。也许我在某个地方缺少引号或某些东西?我是PDO的新手。

这是读取方法:

public function read($select_col, $table_name, $where, $where_condition=null, $where_compare=null, $other=null){

        //This method will return false if the # of where key-value pairs don't match up with the # of $where_condition items.
        //If it works, it will return a 1-dimensional array if only one row is found. If more than one row, then it will be a 2D array.
        //      It will return an associative array.

        //$select_col can be an array or a variable (words or just "*")
        //$table_name is just $table_name (most likely the $table_name var given by object)
        //$where is an associative array with keys as column names and values as the value for the test. 
        //      Code below will add ":" in front of key to make it a named parameter.
        //$where_condition allows user to create other where conditions (ie. "<" or ">". It can be a single variable or an array)
        //$other would be room for other stuff like "ASC LIMIT 1"
        $errors = array();
        $sql = '"SELECT ';

        //if $select_col is an array, then put commas after each item except for the last one
        if(is_array($select_col)){
            $s_count = count($select_col);
            for($s=0; $s<$s_count; $s++){
                $sql .= $select_col[$s];
                if($s<($s_count-1)){
                    $sql .= ", ";
                }
            }
        } else{
            $sql .= $select_col;
        }
        $sql .= " FROM " . $table_name;

        //if $where values are given, then add them to sql. Named parameters are generated from the keys by adding ":" in front of each key
        if(!empty($where)){
            $w_count = count($where);
            //if there are $where_condition values, then make sure they match up to the number of $where key-value sets. 
            //If they don't match up, then return false and stop.
            if(!empty($where_compare)){
                $wc_count = count($where_compare);
                if($w_count!=$wc_count){
                    return false;
                    $exit();
                }
            }
            $sql .= " WHERE ";
            for($w=0; $w<$w_count; $w++){
                $sql .= key($where);
                if(!empty($where_compare)){
                    $sql .= " " . $where_compare[$w] . " ";
                } else{
                    $sql .= " = ";
                }
                $sql .= "':" . key($where) . "'";
                next($where);
                if($w<($w_count-1)){
                    if(empty($where_condition)){
                        $errors[] = "WHERE condition(s) is/are missing (ie. AND, OR)";
                    } else{
                        $sql .= " " . $where_condition[$w] . " ";
                    }
                }
            }
        } 
        //At this point, $where keys and named parameters are set up or it just skipped where section because there are no where values
        if(!empty($other)){
            $sql .= " " . $other;
        }
        $sql .= '"';

        $stmt = $this->dbc->prepare($sql);
        if(!$stmt){
            $errors[] = "Failed to prepare query. " . $this->dbc->errorInfo();
        }
        foreach ($where as $key => $value) {
            $named_param = "':" . $key . "'";
            if(is_numeric($value)){
                $type = "PDO::PARAM_INT";
            } else{
                $type = "PDO::PARAM_STR";
            }
            $stmt->bindValue($named_param, $value, $type);
        }
        $execute = $stmt->execute();
        if(!$execute){
            $errors[] = "Query failed to execute. " . $this->dbc->errorInfo();
        }
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        //if just one row is returned, it returns a one-dimensional array. If more than one row, then it is a two-dimensional array.
        if(!empty($errors)){
            return $errors;
        } else{
            return $result;
        }   
} 

这是使用read方法的身份验证方法:

public static function authenticate($username="", $pw=""){
    global $db;

    $hashed_pw = self::encrypt_pw($username, $pw);
    $where = array('username' => $username, 'pw' => $hashed_pw);
    $where_condition = array("AND");

    $id = $db->read("user_id", "users", $where, $where_condition);
    if(is_numeric($id) AND $id!=0){
        return true;
    } else{
        return false;
    }
}

2 个答案:

答案 0 :(得分:0)

为什么"$sql = '"SELECT ';中有$sql .= '"';

$sql已经是一个字符串,如果这是你想要做的。您所做的工作在实际"查询之前和之后添加了select个文字。删除它们可以解决您的问题。

答案 1 :(得分:0)

$sql = '"SELECT ';

您在查询中添加了额外的双引号。这不是必需的。将该行更改为:

$sql = 'SELECT';

这应解决问题。