PHP中的参数化查询

$postid = $_GET['p'];

$stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
$stmt->bindValue(':postid', $postid);
$stmt->execute();

while($postRows = mysqli_fetch_assoc($stmt)){
    $posts[] = $postRows;
}

The above code does not work.

Usually I'd do:

$postid = mysqli_real_escape_string($conn,$_GET['p']);
$result = mysqli_query($conn,"SELECT * FROM posts WHERE post_id='$postid'");

while($postRows = mysqli_fetch_assoc($result)){
    $posts[] = $postRows;
} 

which works for me.

I can't seem to get my head around this because online explanations do a poor job of actually explaining how to do these, so I have been using mysqli_real_escape_string instead but I understand it can be vulnerable. Can anyone help me understand how to properly do these queries?

You can try this code

  $stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
  $stmt->bindValue(':postid', $postid, PDO::PARAM_INT);
  $stmt->execute();
  $posts = $stmt->fetchAll(PDO::FETCH_ASSOC);

This could help you:Mysql prepare statement - Select

And an Example from PHP on using bindValue()website(http://php.net/manual/en/pdostatement.bindvalue.php example#2):

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < ? AND colour = ?');
$sth->bindValue(1, $calories, PDO::PARAM_INT);
$sth->bindValue(2, $colour, PDO::PARAM_STR);
$sth->execute();
?>

In this example they are specifying parameter type in the bindValue() statement such as PDO::PARAM_STR and PDO::PARAM_INT. You too try specifying your parameter as such.

Or you can also prepare statements and bind values using bindParam(':placeholder',$variable_or_value); (http://www.w3schools.com/php/php_mysql_prepared_statements.asp)

Prepared statements are used for executing same query multiple times with different or changing values. It gives more efficiency. For simple or random queries there is no need to prepare statements infact it will only decrease the effificeny b creating overheads for preparations. And prepared statements are generally applied on INSERT and UPDATE statements

I guess what you want to do might be:

$stmt = $conn->prepare('SELECT * FROM posts WHERE post_id = ?');
//Use 's' for a string or 'i' for an integer
$stmt->bind_param('s', $postid);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) 
{ }

As I said in comments, you are mixing MySQL APIs (mysqli_ and PDO).

You need to use the same API from connecting to querying. Those different APIs do not intermix.

In order to use PDO, you need to:

Then if you want to use PDO with prepared statements:

You cannot connect with mysqli_ then mix MySQL functions with PDO.

That's how it rolls.


Footnotes:

If you want to stick with mysqli_, then it too has prepared statements.

The choice is yours. Remember to use the same MySQL API.


Error checking:

Add error reporting to the top of your file(s) which will help find errors.

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

// rest of your code

Sidenote: Displaying errors should only be done in staging, and never production.