简体   繁体   中英

Using PDO prepared statements MySQL error

I'm trying to create an OOP style CRUD class in PHP and using PDO prepared statements to protect against injections. My connection is working and I can perform regular SQL queries from the class but when I try to incorporate PDO's prepare function, I get an error that I either have a MySQL syntax error or PDO prepare is undefined.

The error gets thrown at $p_query = $db->prepare($sql) line. Can anyone spot what I am doing wrong?

<?php
require_once 'dbconfig.php';

class Crud {
    protected $db;

    private static function fetchQuery($sql, $values) {
        echo $sql;
        var_dump($values);
        $db = Db_conn::pdoBuilder();
        $p_query = $db->prepare($sql);
        $p_query->execute($values);
        $results = $p_query->fetch(PDO::FETCH_OBJ);
        return $results;    
    }
    public static function show($tbl, $id) {
        $sql = '"SELECT * FROM (:tbl) WHERE id = (:id)"';
        $values = [':tbl' => $tbl, ':id' => $id];
        $results = self::fetchQuery($sql, $values);
        return $results;

    }

    public static function listAll($tbl) {
        $sql = '"SELECT * FROM (:tbl)"';
        $values = [':tbl' => $tbl];
        $results = self::fetchQuery($sql, $values);
        return $results;
    }
}

First off:

$sql = '"SELECT * FROM ?"';

Why are you quoting your query? It should be:

$sql = 'SELECT * FROM ?';

Next:

$values = [':tbl' => $tbl];

Where is the placeholder :tbl in your query? You're using ? , change the $sql string to:

$sql = 'SELECT * FROM :tbl';

Which immediately poses another problem: the table you're using in your prepared statement can't be bound after you create the prepared statement. Impossiburu. Never going to happen. The best you can do is something like:

$sql = sprintf(
    'SELECT * FROM `%s`',
    //remove illegal chars
    str_replace([' ', '\\', '`', '"', "'"], '', trim($tbl))
);

Lastly, applied to this bit:

$sql = '"SELECT * FROM (:tbl) WHERE id = (:id)"';
$values = [':tbl' => $tbl, ':id' => $id];
$results = self::fetchQuery($sql, $values);

This means you'll have to write:

$sql = sprintf(
    'SELECT * FROM `%s` WHERE id = :id',
    $tbl
);
$values = [':id' => $id];
return self::fetchQuery($sql, $values);

But really, you're not using prepared statements as well as perhaps you could. The best thing about prepared statements is that they're reusable . Wrapping PDO to get a cleaner API hasn't been done as far as I know. Most attempts turn out to actually lessen the power of the extension, or build a bloated abstraction layer around it. That needn't be a bad thing, provided you're building a full-blown ORM/DBAL. I've been quite vocal about this stuff here , you might want to read through it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM