1

I've got a strange problem. There are 2 queries.

$sql = "SELECT  `content_auftrag_id` 
        FROM `content` 
        WHERE `content_id` = '".$content_id."' LIMIT 1";
    $ergebnis = $db->prepare( $sql );
    $ergebnis->execute();
    $ergebnis->bind_result( $content_auftrag_vorhanden );

$content_auftrag_id = "test";
$sql = "UPDATE `content` SET `content_auftrag_id` = '".$content_auftrag_id."' 
        WHERE `content_id` = '".$content_id."'";
        $ergebnis2 = $db->prepare( $sql );
        $ergebnis2->execute();

When I use them both, then an error occurs for the second one. If I only run the the second, then it works fine. How can it be that both together cause an error? All variables are there and correct.

Thanks!

Crayl
  • 1,883
  • 7
  • 27
  • 43
  • -1, you managed to produce SQL-injectable code by misusing PDO. – Johan Jun 12 '11 at 20:49
  • @Johan - Could you please explain how I did it? – Crayl Jun 12 '11 at 21:05
  • @Johan: based on method names, it was Mysqli, not PDO in use here. But you're still right. – bob-the-destroyer Jun 12 '11 at 21:16
  • 1
    @Crayl: you'll want to read through the `bind_param()` method page to gain more insight into how it's done: http://us.php.net/manual/en/mysqli-stmt.bind-param.php. A hint though: often it really doesn't matter if you don't know the variable type when making your `$types` string - "S" generally covers everything anyway, and Mysql will convert it to the appropriate column format on its end. – bob-the-destroyer Jun 12 '11 at 21:17
  • 1
    @Crayl, you are injecting your $vars into the query by concatenation. However mysqli supports parameters. You should use those instead then you're no longer at risk. – Johan Jun 12 '11 at 21:21
  • 2
    @Crayl, appreciate it. 95% of [mysql] [php] questions by new users have SQL-injection flaws in them. Even big firms like SONY have SQL-injection holes all over their websites. And it's sooo easy to prevent them. You only need to follow a few basic rules. See e.g. here: http://stackoverflow.com/questions/332365/xkcd-sql-injection-please-explain and here: http://stackoverflow.com/q/5811834/650492 – Johan Jun 12 '11 at 21:35

3 Answers3

3

Okay, I think you didn't quite got the idea behind PreparedStatements. You shouldn't directly insert the parameters in your SQL-String, but use ?-placeholders and bind them in the Query using the bind_param()-method.

Your error seams to appear here:

$ergebnis2 = $db->prepare( $sql );

This function returns false if it wasn't successful. You should check if the value of ergebnis2 is not false.

Also, you should use the error-method to see the last appeared MySQL-Error.

Lukas Knuth
  • 25,449
  • 15
  • 83
  • 111
2

If $ergebnis2 is 'not an object', then I guess it must be false. Which means the prepare() call failed for whatever reason.

What does $db->error return after you have called the 2nd prepare? Always check your return values, its basic debugging

carpii
  • 1,917
  • 4
  • 20
  • 24
2

You can only work on one prepared query at a time, so to speak. See Mysqli::execute() method:

"When using mysqli_stmt_execute(), the mysqli_stmt_fetch() function must be used to fetch the data prior to performing any additional queries."

You can also use the store_result() method to remove this block as well to perform the next query.

Also, take heed from those who warn you about abusing prepared statements like your example. Though it works without error if you don't actually have any parameters to bind to, it basically throws sql injection prevention out the window.

bob-the-destroyer
  • 3,164
  • 2
  • 23
  • 30