I am trying to create a search function for a site and have created the sql code, which was generated from PHPMYADMIN, see below;
$sql = "SELECT * FROM `bg85ow`.`sessions` WHERE CONVERT(`SessionName` USING utf8) LIKE '%:SessionName1%'";
Here is the PHP code processing the query;
//bind params
$SessionName1 = filter_input(INPUT_GET, 'search');
$stmt -> bindValue(':SessionName1', $SessionName1, PDO::PARAM_STR);
//execute
$success = $stmt -> execute();
if (!$success){
print $stmt->errorInfo()[2]; //PDO driver error message
}
else{
}
//array
$r = $stmt->fetchAll(PDO::FETCH_ASSOC);
$dbh = null;
if(!$r)
{
echo "No Results";
}
foreach ((array) $r as $row) {
echo $row['SessionId'];
echo $row['SessionName'];
}
For some reason this will not return any results the execute part is working fine and passing the success test but then once it gets to the array it returns no results.
I checked and $SessionName1 has the term in it from search so it is being passed to the query ok.
When I change the %:SessionName1% to football which is the search term I am testing with, the code returns the results fine but once changed back to :SessionName1 it will not return the results even though the search term is exactly the same.
Can anybody see what I am doing wrong, I spent ages looking at this and cannot see the error.
I have searched everywhere for an answer to this but I couldn't find one specific to this issue, also I am a beginner with PHP and SQL.
Try this Example : Check where is you are wrong.
// Get the keyword from query string
$keyword = $_GET['keyword'];
// Prepare the command
$sth = $dbh->prepare('SELECT * FROM `users` WHERE `firstname` LIKE :keyword');
// Put the percentage sing on the keyword
$keyword = "%".$keyword."%";
// Bind the parameter
$sth->bindParam(':keyword', $keyword, PDO::PARAM_STR);
Related
I'm making a song database system, and I'm trying to implement a way for users to search songs based on a category to search (song's name, artist's name, album name, genre etc) and a given search term. To accommodate user input and protect against SQL injection, I'm using a prepared statement made with bind variables, however I'm having trouble with what I currently made:
search("genre", "electropop", $db);
function search($column, $term, $db) {
try {
$sql = "SELECT * FROM Songs WHERE :column=:term;";
$stmt = $db->prepare($sql);
$params = array("column" => $column,
"term" => $term);
$stmt->execute($params);
$arr = $stmt->fetchALL(PDO::FETCH_ASSOC);
print (json_encode($arr));
}
catch(PDOException $ex) {
catch_error("The search failed.", $ex);
}
}
Whenever I test this, I get an empty array back: [ ]
I tested my query ("SELECT * FROM Songs WHERE genre='electropop'") in phpmyadmin and it checks out (gave me back entries).
The correct syntax for WHERE clauses in SQL is that the term needs to be surrounded by quotations (https://www.w3schools.com/sql/sql_where.asp) so I tried escaping quotation marks around the term:
...
$sql = "SELECT * FROM Songs WHERE :column=\':term;\'";
...
But then it fails to even see :term as a token to bind variables to later.
Not sure how to go about solving this. I assumed the empty array is due to a valid search but just no results, but perhaps I'm not correctly using a prepared statement. Any help would be much appreciated! Thanks!
You missed the : before term param. Don't need to bind column name. Just use the $column var instead of :column.
search("genre", "electropop", $db);
function search($column, $term, $db) {
try {
$sql = "SELECT * FROM Songs WHERE $column=:term;";
$stmt = $db->prepare($sql);
$params = array(":term" => $term);
$stmt->execute($params);
$arr = $stmt->fetchALL(PDO::FETCH_ASSOC);
print (json_encode($arr));
}
catch(PDOException $ex) {
catch_error("The search failed.", $ex);
}
}
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;
}
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.
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;
}
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>";
}
So, first off, I know there are certain rules you have to follow when preparing a LIKE statement with PDO. I have already looked these up and I'm trying my best to follow them, but the query consistently returns no results even though I know the query itself is legitimate (MySQL command line client works correctly with the query).
This is for a school project; I need to make a website with a MySQL/php backend for a fictional bookstore.
I have a class in a php script called DBConnection. It is in a separate namespace (hence the backslashes for PDO objects and functions). This is part of it:
<?php
class DBConnection {
// ...
public function prepAndExecute($sql, $args) {
try {
$stmt = $this->conn->prepare($sql);
for($i = 1; $i <= count($args); $i++) {
$stmt->bindValue($i, $args[$i-1], \PDO::PARAM_STR);
}
$stmt->execute();
return $stmt;
} catch(\PDOException $e) {
return false;
}
}
}
?>
The actual MySQL query I am trying to run:
SELECT ISBN, Title, Author, Price FROM Book WHERE Title LIKE "%rich%";
My attempt at using a PDO Prepared Statement to run this on the website:
<?php
// based on the search form from the previous page
// (all values are set correctly by the form, already tested)
$criteria = $_POST["searchCriteria"]; // "Title" (from a <select> element)
$term = $_POST["searchTerm"]; // "rich" (from the text box)
$conn = new DBConnection(); // uses namespace correctly, just didn't
// include here for simplicity
$sql = "SELECT ISBN, Title, Author, Price FROM Book WHERE ? LIKE ?";
$stmt = $conn->prepAndExecute($sql, array($criteria, "%" . $term . "%"));
// I have also tried $term = "%" . $term . "%", still no luck
echo $stmt->rowCount(); // 0
?>
I ran the above query in the MySQL command line, and got 1 result as expected. I know the class/functions work because I use that same function to run all other SELECT and INSERT queries, and have had no problems until I try to run this LIKE statement.
Am I doing something wrong? Because I double and triple checked everything and could have sworn I was doing this right.
http://php.net/manual/en/pdostatement.bindparam.php
$sth = $dbh->prepare('SELECT * FROM `users` WHERE `firstname` LIKE :keyword');
// Put the percentage sing on the keyword
$keyword = "%".$keyword."%";
// Bind the parameter
$sth->bindParam(':keyword', $keyword, PDO::PARAM_STR);
Would someone please me with the code below, I am inexperienced in this area and my class in SQL was "A long time ago in a galaxy far, far away..." I know the connection string works because I have used it in other functions with this app. I have even used the code below for retrieving *rows from another table in another function, for the most part, except that I didn't use the WHERE clause.
First, I am able to store IP addresses in the table using a function and it is working well. Now I want to check to see if a given one exist in this table. Partial code is given below.
What seems to always return is 0 rows. I have put in test data into the table and hard-coded the $ipA, but I still get 0 rows return. Please help if possible and thanks for the effort spent.
function checkDB($ipA) {
require_once('connection.inc.php');
$resultAns = "";
//create db connection
$conn = dbConnect();
//init prepared stmt
$stmt = $conn->stmt_init();
//Set sql query for ipAddress search
//prepare the SQL query
$sql = 'SELECT * FROM ipAddress WHERE ipA = ?';
//submit the query and capture the result
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', $ipA);
$stmt = $stmt->execute();
//if qry triggers error affeted_rows value becomes -1 &
//php treats -1 as true; so test for greater than 0
$numRows = $stmt->num_rows; //not to sure about the syntax here
}
// I want to know if the query brought back something or not, I don't what
// to know exactly what, only that it found a match or did not find a match.
// echos are for testing purposes to show me where I am landing.
if ($numRows == 0) {
echo '<script type="text/javascript">window.alert("numRows = 0")</script>';
$resultAns = 0;
} elseif ($numRows == 1) {
echo '<script type="text/javascript">window.alert("numRows = 1")</script>';
$resultAns = 1;
}
return $resultAns;
}
Try storing the result after you execute
$stmt->store_result();
Use $stmt->store_result(); before you call num_rows.
While the others caught one reason that $numRows would never receive a value other than 0, the other piece of code that was flawed and caused problems was...
$stmt = $stmt->execute(); which should have been just $stmt->execute();
I must have mixed it up with other code I wrote from somewhere else.
Thanks for the answers, they did help.
$q = $db->query(" SELECT username FROM users WHERE userident = '1' ");
echo $q; //error
print_r $q; //prints the query information (SELECT ... etc)
How do I go about getting the specific value of the element I am querying? Say the element under column username and where userident equals '1' contains the value "Patrick"; how do I initialize this string into a variable?
//same query as above
$user = $q;
echo $user; //prints "Patrick"
Sorry if this is something so rudimentary and mundane, but I've never done this outside of a foreach() loop. I'd normally iterate through rows to print specific details. The below works, but the foreach() is unnecessary as far as I understand.
foreach($q as $p) {
$user = $p["username"];
}
echo $print; //this correctly prints "Patrick"
Surely there's a method I missed somewhere?
Using the query method pretty much defeats the purpose of using prepared statements. Plus, I believe for what you're looking for, it isn't quite right.
<?php
if (!isset($_POST['id'])) {
exit;
}
$userId = $_POST['id'];
$db = new PDO(/* Stuff */);
$sql = '
SELECT username
FROM users
WHERE id = :id';
// Get a prepared statement object.
$statement = $db->prepare($sql);
// Bind a parameter to the SQL code.
$statement->bindParam(':id', $userId, PDO::PARAM_INT);
// Actually get the result.
$result = $statement->fetch(PDO::FETCH_ASSOC);
// Close the connection.
$statement->closeCursor();
// Print the result.
print_r($result);
Alternately you can use $statement->fetchAll() to gather more than one result.
Edit: I didn't actually run this code, so you might have to tinker with it to get it working right.