-5

ここで「SQLSTATE[23000]: Integrity constraint violation: 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 の 2 つのエントリがあるため、ID を複製できません。
問題は何ですか?
ありがとうございました!

4

1 に答える 1

3

なぜ誰もまだそれを発見していないのかはわかりません.通常、このようなばかげた基本的な構文エラーを発見するために、3〜5人の人々が周りにいます. これは、クエリ var_dumped から明確にわかりました。

最も重要なプリペアド ステートメントのメリットの1 つは、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?私のアプローチでは、クエリ内の 1 つの単語を変更するだけです。あなたが深刻な問題に直面している間。SELECT クエリの場合は、さらに面倒です。

于 2013-06-22T05:49:50.957 に答える