-5

在此处遇到“ SQLSTATE [23000]:完整性约束违规:1062 Duplicate entry '0' for key 'id' ”的问题,

<? if (!defined("sKEY")) { exit("Houston, We've Got a Problem"); }
class PDOAct
{
    public $db;
    function __construct()
    {
        try {
            $this->db = new PDO(DBdriver.':host='.DBhost.';dbname='.DBbase, DBuser, DBpass);
            $this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
    }
    //
    //
    function select($base, $row, $val, $type)
    {
        try {
            if (isset($row[0]) && isset($val[0]) && isset($type[0]))
            {
                if (isset($base['select']) && $base['select'] != "*")
                {
                    for ($i=0; $i<count($row); $i++)
                    {
                        if ($i < 1)
                        {
                            $q = "SELECT `".$base['select']."` FROM `".$base['table']."` WHERE `".$row[$i]."` = ':".$row[$i]."'";
                        } else {
                            $q = $q." AND `".$row[$i]."` = ':".$row[$i]."'";
                        }
                    }
                } elseif (!isset($base[select]) || $base[select] == "*") {
                    for ($i=0; $i<count($row); $i++)
                    {
                        if ($i < 1)
                        {
                            $q = "SELECT * FROM `".$base['table']."` WHERE `".$row[$i]."` = ':".$row[$i]."'";
                        } else {
                            $q = $q." AND `".$row[$i]."` = ':".$row[$i]."'";
                        }
                    }
                }
            } elseif (!isset($row[0]) && !isset($val[0]) && !isset($type[0])) {
                if ($base['select'] != "" && $base['select'] != "*")
                {
                    $q = "SELECT `".$base['select']."` FROM `".$base['table']."`";
                } elseif ($base['select'] == "" || $base['select'] == "*") {
                    $q = "SELECT * FROM `".$base['table']."`";
                }
            } else {
                exit("Query error!");
            }
            $do = $this->db->prepare($q);
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
        $arr = array('do' => $do, 'row' => $row, 'val' => $val, 'type' => $type);
        return $arr;
    }
    //
    //
    function insert($base, $row, $val, $type)
    {
        try {
            if (isset($row[0]) && isset($val[0]) && isset($type[0]))
            {
                for ($i=0; $i<=count($row); $i++)
                {
                    if ($i < 1)
                    {
                        $q = "INSERT INTO `".$base['table']."` (`".$row[$i]."`";
                    } elseif ($i == count($row)) {
                        $q = $q.") VALUES (";
                        for ($j=0; $j<=count($row); $j++)
                        {
                            if ($j < 1)
                            {
                                $q = $q."':".$row[$j]."'";
                            } elseif ($j == count($row)) {
                                $q = $q.")";
                            } else {
                                $q = $q.", ':".$row[$j]."'";
                            }
                        }
                    } else {
                        $q = $q.", `".$row[$i]."`";
                    }
                }
            } else {
                exit("Query error!");
            }
            $do = $this->db->prepare($q);
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
        $arr = array('do' => $do, 'row' => $row, 'val' => $val, 'type' => $type);
        return $arr;
    }
    //
    //
    function execute($arr)
    {
        $do = $arr['do'];
        $row = $arr['row'];
        $val = $arr['val'];
        $type = $arr['type'];
        try {
            for ($i=0; $i<count($row); $i++)
            {
                $bindrow = ':'.$row[$i];
                $bindtype = "PDO::PARAM_".strtoupper($type[$i]);
                $do->bindValue($bindrow, $val[$i], $bindtype);
            }
            $do->execute();
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
    }
    //
    //
    function err($e)
    {
        file_put_contents('log'.DIR_SEP.'PDOerrors.txt', $e."\n", FILE_APPEND);
        exit("Houston, We've Got a Problem");
    }
}
?>

当我尝试像这样插入查询时:

$db = new PDOAct;
    $base   = array("table" => "users");
    $row    = array("id",  "login", "pass",  "level", "date",       "name",  "sex", "birth");
    $val    = array( 4,    "Paul",   135246,   2,     "2013-06-22", "Paulio",  1,    "1996-06-25");
    $type   = array("int", "str",   "int",   "int",   "str",        "str",   "int", "str");
    $res = $db->execute($db->insert($base, $row, $val, $type));
    print_r($res);

在表中,我有两个 id 为 0 和 1 的条目,所以它不能重复 id..
那么有什么问题呢?
谢谢!

4

1 回答 1

3

不知道为什么还没有人发现它——通常周围有 3 到 5 个人来发现像这样愚蠢的基本语法错误。从查询 var_dumped 中可以清楚地看到。

准备好的语句最重要的好处之一 - 它确实完成了格式化,而不是部分格式化,这是 PHP 人员使用的。因此,当使用准备好的语句时,不必手动格式化值,以避免双重格式化。

$q .= " AND `".$row[$i]."` = :".$row[$i];

它必须是。

请注意,您的函数对 SQL 注入是开放的。

此外,我发现整套功能非常不可用。我不知道你为什么要用如此有限的 SQL 子集束缚你的手。为什么不写干净的纯 SQL?为什么要用一些除了作者之外的任何人都无法阅读的自制语法来代替它?

另请注意,所有这些“休斯顿我们遇到问题”都是完全无用的。如果你摆脱了这种 try-catch 的东西,PHP 将完成所有工作,记录和退出并告诉问题,并且比你的代码做得更好。

我会怎么做:

$db   = new safeMysql();
$data = array("id" => 4, "login" => "Paul", "pass" => 135246, "level" => 2, 
              "date" => "2013-06-22", "name" => "Paulio",  "sex" => 1, 
              "birth"=> "1996-06-25");
$db->query("INSERT INTO users SET ?u", $data);

看,我保持 SQL 自然,这使我的查询灵活。如果我需要INSERT IGNORE怎么办?还是REPLACE代替INSERT?使用我的方法,我将只更改查询中的一个单词。虽然您将进行深度修复。对于 SELECT 查询,它会更加麻烦。

于 2013-06-22T05:49:50.957 回答