سؤال

I am trying to get a database query page to work but cant seem to do so.

my Code so far (here I tried bindValue, but previously tried bindParam and got the same result):

    var_dump($_POST);


    $dbh = new PDO ("mysql:host=$myServer;dbname=$myDB", $myUser, $myPw);
    $columName = $_POST["columName"];
    $tblName = $_POST["tblName"];
    $valueName = $_POST["valueName"];
    $specificValue = $_POST["specificValue"];

    $stmt = $dbh->prepare("SELECT :columName FROM :tblName Where :valueName = :specificValue");
    $stmt->bindValue(":columName", $columName);
    $stmt->bindValue(":valueName", $valueName);
    $stmt->bindValue(":tblName", $tblName);
    $stmt->bindValue(":specificValue", $specificValue);
    $stmt->execute();

    $result = $stmt->fetch();

    if(empty($result)){echo "empty";}
    print_r ($stmt);
    print_r($result);

Printing result and $stmt brings following results:

empty PDOStatement Object ( [queryString] => SELECT :columName FROM :tblName Where :valueName = :specificValue )

What did I do wrong? What could I try to get it to work? I am new to the whole coding thing, so please ask if I forgot any code or other important information! Thanks!

هل كانت مفيدة؟

المحلول

Placeholder parameters can only represent VALUES in the query. Tables, field names, sql key words, etc.. are all impossible to use placeholders on.

If you need to build a dynamic query and replace field/table names, then you'll have to use good old string construction methods, and be aware that you'll be opening yourself to SQL injection attacks again:

$sql = "SELECT * FROM $foo WHERE $bar = :baz";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':baz', $baz);

نصائح أخرى

I'm afraid you need to rethink how parameterised queries work. It's not just a case of magically inserting data in a safe way. It's about distingushing between the structure of a query and the data.

So the database name, the column names, the table names and any SQL keywords are part of the structure of the query. Every time you run the query, they will be the same.

The data, however, can change between running the query.

So the structure needs to be in place when the query is prepared. However, you obviously can't just plonk the $columName variable etc into the query for SQL injection reasons. If you really need to have flexible queries like this (nb that you probably don't) you need to create a whitelist of allowed values, either in your code or retrieved from the database.

Your query is invalid (you're using parameters for object identifiers) but you are not getting any notification because you have neither configured PDO to throw exceptions nor are calling the error check functions manually.

Add the PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION option to PDO's constructor:

$dbh = new PDO ("mysql:host=$myServer;dbname=$myDB", $myUser, $myPw, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

Once you do so, you'll get a prompt exception on the exact issue, e.g.:

PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''user' Where 'login' = 'john'' at line 1 in [...]

As you can see, this is trying to run a query like (e.g.):

SELECT 'user_id'
FROM 'user'
Where 'login' = 'john'

Additionally, beware of SQL injection. It's terribly unsafe to compose SQL queries using data from $_POST.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top