Reputation: 578
So I have look at so many post, web sites and video and now I am so confused! I can't seem to get it right. How do you stop injection in this PHP/PDO. I have this code that works, but it allows injection.
//*THIS WORKS BUT ALLOWS INJECTION
//*
//The variable $word comes from another php file where the search is created.
public function getAllCards($word) {
$sql = "SELECT * FROM carddbtable WHERE businessNameDB='".$word."'";
foreach ($this->conn->query($sql) as $row) {
echo json_encode($row)."<br>"."<br>";
}
$db = null;
}
With this new code I am trying to remove the variable "$word" from the "SELECT * FROM " statement to stop the injection and add the "prepare" and the error checking and the "execute" statement, but I can't get it right. How would I do this? FYI this is a GoDaddy shared server.
//Getting the search "word" from the GetCards.php
public function getAllCards($word) {
//Empty var to store all returned info from db
$returnArray = array();
// sql statement to be executed
$sql = "SELECT * FROM carddbtable WHERE businessNameDB=':word";
// prepare to be executed
$statement = $this->conn->prepare($sql);
// error occurred
if (!$statement) {
throw new Exception($statement->error);
}
// execute statement
$statement->execute( :word => '$word' );
//run the query
foreach ($this->conn->query($statement) as $row) {
echo json_encode($row)."<br>"."<br>";
}
// store all appended $rows in $returnArray to be sent to app
$returnArray[] = $row;
}
Upvotes: 0
Views: 93
Reputation: 578
I got this working
//*FUNCTION TO GET CARD FROM SEARCH WORD CALLED FROM GetCards.php
public function getAllCards($word) {
//Connect to db using the PDO not PHP
$db = new PDO('mysql:host=localhost;dbname=xxxx', 'xxxx', 'xxxx');
//Here we prepare the SELECT statement from the search word place holder :word
$sql = $db->prepare('SELECT * FROM carddbtable WHERE businessNameDB=:word');
//We execute the $sql with the search word variable"$word"
$sql->execute([':word' => $word]);
//Looping through the results
foreach ($sql as $row)
//Print to screen
echo json_encode($row). "<br>"."<br>";
}
Upvotes: 0
Reputation: 578
This is what i have now.
//Getting the search "word" from the GetCards.php
public function getAllCards($word) {
//Empty var to store all returned info from db
$returnArray = array();
// prepare to be executed sql statement to be executed if not entered word
$statement = $this->conn->prepare("SELECT * FROM carddbtable WHERE businessNameDB=:word");
// error occurred
// if (!$statement) {
// throw new Exception($statement->error);
// }
// execute statement
$res = $statement->execute([ 'word' => $word ]);
//run the query
foreach ($this->conn->query($res) as $row) {
echo json_encode($row)."<br>"."<br>";
}
// store all appended $rows in $returnArray to be sent to app
$returnArray[] = $row;
}
Upvotes: 0
Reputation: 211670
You've almost got it. PDO, like many database drivers, will be responsible for all of the escaping, so just leave the placeholder as plain as possible:
$sql = "SELECT * FROM carddbtable WHERE businessNameDB=:word";
No '
necessary there.
Now when you execute()
a PDO statement you get a result which you need to capture into a variable:
$res = $statement->execute([ 'word' => $word ]);
As Ibu and chris85 point out the '$word'
part is also incorrect. Avoid quoting single variables, it's not only pointless, it can cause trouble, like here where you're binding to literally dollar-sign word, not the value in question. This goes doubly for "$word"
.
Then you fetch from that. Right now you're calling query()
on the statement, which is incorrect.
Another thing to note is kicking the habit of making throw-away variables like $sql
as these are just junk. Instead pass the argument directly:
$statement = $this->conn->prepare("SELECT * FROM carddbtable WHERE businessNameDB=:word");
This avoids accidentally mixing up $sql3
with $sql8
if you're juggling a bunch of these things.
Upvotes: 4