PDO WHERE Condition Refuses to Fetch Rows - php

I have a query:
//Connect to DB w/ PDO
$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$id = $_GET["id"];
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?", PDO::FETCH_ASSOC);
$stmt->bindParam(1, $id);
try{
$stmt->execute();
}catch(PDOException $err){
//some logging function
}
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){
//select column by key and use
$FirstName = $result['Name'];
}
?>
This is the output:
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
The ID is being filled from the $id variable.
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$Name = $row['Name'];
But when try to get
$Name = row['Name'];
I get UNDEFINED VARIABLE: FIRSTNAME
When I run:
<?php var_dump($stmt) ?>
I get this:
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
What am I doing wrong here? It works in another file.
But ID WILL NOT work here even know it's in the query field.

I can see you are fairly new to PHP and PDO.
You have created a script that is vulnerable to SQL-injection,so we will fix that to.
It is important to understand what pdo is doing in order to understand what is going wrong. It will also make you understand the security problem you have created for yourself.
PDO makes it posible for the programmer to "compile" the SQL query before passing it the parameters and execute it.
This has some benefits, mainly it is faster when you want to execute the same query multiple times(with different parameters) and it is much more secure.
Lets take your query as an example:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = $id");
If I would manage to change the contents of $id to something like:
$id="1; SELECT * FROM users;"
The query you would execute would become:
SELECT * FROM nv_hoa WHERE id =1; SELECT * FROM users;
Which would result in you listing every user and password in the user table.
This is a very well know and one of the most dangerous attacks out there.
To counter this, we can use PDO's pre-compiled queries (a.k.a prepared statements)
Instead of:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = $id");
Now use:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?");
Pdo now compiled your query within the $stmt object.
So now you can execute this query (as many times as you want) using the parameters you prefer.
$stmt->execute([$id]);
This executes the compilled query with the $id parameter. If the $id parameter contains SQL code, it will not become part of the query as you have already compiled the query, as so an SQL-Injection attack becomes near to impossible.
Now that your query is executed, you can fetch the results like:
while($row=$stmt->fetch()){
...
}
So in order to make your code work:
//PDO DB Connect to Fetch & Make into Vars from table nv_hoa
try {
//Connect to DB w/ PDO
$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$id = $_GET["id"];
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?");
$stmt->execute([$id]);
while ($row = $stmt->fetch())
{
$Name = $row['Name'];
}
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
Please do yourself(and others) a favor and research/learn a bit more before posting, you are making class-book mistakes that have been discussed and explained multiple times on pretty much every medium (including stackoverflow).

I solved the issue of a bool(false) output from a query even though the query dump had the ID.
Here is the fix.
The output of
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?", PDO::FETCH_ASSOC);
was
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
Which showed the ID was being passed properly. But the ID contained a special character '-' which caused the $stmt->execute([$id]); to break the page because $id was empty.
This was fixed as follows with single quotes.
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = '$id'");
$stmt->bindParam(1, $id);
$stmt->execute();
I have found HUNDREDS of posts about this topic and this solves it. If you varaible has special chacters in a PDO statement you need to do this id = '$id'"

Related

Postgresql not binding in prepared statement for SELECT in PHP

<?php
try
{
global $db;
$user = 'postgres';
$password = '*****'; //For security
$db = new PDO('pgsql:host=localhost;dbname=dnd', $user, $password);
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch (PDOException $ex)
{
echo 'ERROR!!: ' . $ex->getMessage();
die();
}
$table = htmlspecialchars($_REQUEST['table']);
$idNum = htmlspecialchars($_REQUEST['id']);
try {
//$query = "SELECT * FROM $table WHERE id = $idNum"; This works
//$query = "SELECT * FROM $table WHERE id = :number"; This works
$query = "SELECT * FROM :tableName WHERE id = :number";
$statement = $db->prepare($query);
$statement->bindValue(":tableName", $table, PDO::PARAM_STR);
$statement->bindValue(":number", $idNum, PDO::PARAM_INT);
$statement->execute();
$info = $statement->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $excep) {
echo "Opps: " . $excep->getMessage();
die();
}
Okay I'm going crazy here trying to get this to work.
I have a database set up that I need to query from. I receive the query from an AJAX request with the name of the table I want and the id for the item. When I try to query with both variables, the binding does not occur in the prepared statement and instead I get this error code
Opps: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "$1" LINE 1: SELECT * FROM $1 WHERE id = 1 ^
When I have just the straight PHP variables it works fine so I know it can work, but when I want to bind multiple it seems to fail and give a variable number as above.
I can also get it to work if I simply have one of the variables bound, such as the second commented out query in the code - this only works tho if I have the variable I want at the end and not if I wanted to lookup the table spot. (I.E.
$query = "SELECT * FROM :tableName WHERE id = $idNum"; does not work)
I need to cleanse the variables to prevent SQL injection, but I can't do that without binding the variables in a prepared statement. Any help would be appreciated!
According to the PHP manual you can't bind a tablename. As you mentioned it, you can replace it by a variable, but you can't replace it with a placeholder.
So the only solution that will work for you is the query you have above:
$query = "SELECT * FROM $table WHERE id = :number"
This will be what you're looking for. If you want to make it safe for injection, you have to find another way. (Regex for example).
Ref: http://us3.php.net/manual/en/book.pdo.php#69304

PHP/MySQL to PDO

I want to change MySQL to PDO:
$mapa = mysql_fetch_array(mysql_query("select * from mapa where id = ".$postac['mapa']." limit 1"));
$mapa_d = mysql_query("select * from mapa_d where mapa = ".$mapa['id']." ");
PHP:
$_SESSION['postac'] = $_POST['postac'];
try like this so far:
$stmt = $pdo->prepare("SELECT * FROM mapa WHERE id=:mapa");
$stmt->bindValue(':mapa', $postac, PDO::PARAM_STR);
$stmt->EXECUTE();
$postac = $stmt->fetchAll(PDO::FETCH_ASSOC);
mysql update:
mysql_query("update postac set logged = 1 where id = ".$_SESSION['postac']." limit 1");
PDO:
$stmt = $pdo->prepare("update postac set logged = 1 where id:postac");
$stmt->bindValue(':postac', $_SESSION, PDO::PARAM_STR);
$stmt->EXECUTE();
$_SESSION = $stmt->fetchAll(PDO::FETCH_ASSOC);
Does not work.
Pre-Answer Note:
I assume you have already set up a PDO connection construct ($pdo) before trying to run your PDO queries.
$mapa = mysql_fetch_array(
mysql_query("select * from mapa WHERE id = ".$postac['mapa']." limit 1"));
$mapa_d = mysql_query("select * from mapa_d WHERE mapa = ".$mapa['id']." ");
PHP:
$_SESSION['postac'] = $_POST['postac'];
try like this so far:
$stmt = $pdo->prepare("SELECT * FROM mapa WHERE id=:mapa");
$stmt->bindValue(':mapa', $postac, PDO::PARAM_STR);
$stmt->EXECUTE();
$postac = $stmt->fetchAll(PDO::FETCH_ASSOC);
PART 1:
Be Consistent
Your original statement uses a value $postac['mapa'] as an id reference in the MySQL_ query, but then your PDO statement you are passing the whole array as a value into the PDO query.
First, MySQL: id ==> $postac['mapa']
Second, PDO: id ==> $postac
So this is causing an immediate issue as you're passing a whole array in to PDO which is somehow expected to extract one value from this array. This array is being classed as a string with your PDO::PARAM_STR declaration so this is preventing the query from using this value, as it doesn't fit what it's told to expect.
Therefore this returns a NULL query.
So to fix it,
$stmt = $pdo->prepare("SELECT * FROM mapa WHERE id=:mapa");
$stmt->bindValue(':mapa', $postac['mapa'], PDO::PARAM_STR);
$stmt->execute();
$postac = $stmt->fetchAll(PDO::FETCH_ASSOC);
Part 2:
Syntax
$stmt = $pdo->prepare("update postac set logged = 1 where id:postac");
$stmt->bindValue(':postac', $_SESSION, PDO::PARAM_STR);
$stmt->EXECUTE();
$_SESSION = $stmt->fetchAll(PDO::FETCH_ASSOC);
As above, you're passing the whole $_SESSION array as a PARAM_STR value, so it's returning VOID /NULL. You also have a syntax fault that you're using WHERE id:postac, but you really mean WHERE id = :postac be careful of missing out syntax such as = !!.
PART 3:
Error Checking
It is well worth exploring and learning how to get useful error feedback on PHP PDO, as it will save you posting to StackOverfow X times a day (hopefully!)!
There is a good answer here about how to setup PDO to output errors. It is also well worth browsing the PHP Manual for PDO error checking details.

PDO Prepared Statements and MSSQL databases not functioning correctly

I'm having a problem running prepared queries on a MSSQL database using PDO. I can connect to the database and run SELECT queries with no parameters, but now I'm trying to run a simple SELECT query with one parameter, :user. However, the code does not return any values, despite the fact that there definitely is a database row with that value in. Here's the code I'm using:
$db = new PDO('dblib:host='.$dbHost.';dbname='.$dbName.';charset=utf8mb4',$dbUser, $dbPass);
$stmt = $db->prepare('SELECT * FROM customer WHERE email_address = :user ');
$stmt->bindValue(":user", $_SESSION["username"], PDO::PARAM_STR);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
I receive no output from the var_dump. I know that in the database there is a correct row, so I tried:
$stmt = $db->prepare("SELECT * FROM customer WHERE email_address = 'the#email.com'");
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
And yet still no value was returned. Am I doing something wrong with PDO? If I type this exact query into the query bar it runs.
you forgot to execute your query.
right after the paramter binding, put this code:
$stmt->execute();
Ok, I'm an idiot. Forgot to execute the query. Amended code for people in the same predicament:
$db = new PDO('dblib:host='.$dbHost.';dbname='.$dbName.';charset=utf8mb4',$dbUser, $dbPass);
$stmt = $db->prepare('SELECT * FROM customer WHERE email_address = :user ');
$stmt->bindValue(":user", $_SESSION["username"], PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

WHERE statement inside if condition in SQL

Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array

Why am I receiving a PDO query error?

Apologies in advance because I'm really unsure how to ask this question so if you need to know anything then please comment rather than downvote and I will edit.
I have teaser links on my main page which when clicked open up a window with the full article. I'm currently converting my MySQL code over to PDO and have gotten a little stuck.
In MySQL I used to be doing the following (Here, $foo_query is the query from the first page):
$id = $_GET['id'];
$sql = "SELECT id, postdate, title, body FROM FooBarTable WHERE id = $id";
if ($foo_query = mysql_query($sql)) {
$r = mysql_fetch_assoc($foo_query);
$title = $r["title"];
$body = $r["body"];
}
Which is simple to understand to me. I've been trying to convert this using what I know, and it turns out I don't know very much. So far I have the following:
$id = $_GET['id'];
$sql = $DBH->prepare("SELECT id, postdate, title, body FROM FooBarTable WHERE id = :id OR id = $id");
$sql->bindParam(':id', $_REQUEST['id'], PDO::PARAM_INT);
if ($foo_query = $DBH->query($sql)) {
$r->setFetchMode(PDO::FETCH_ASSOC);
$r = $foo_query->fetch();
$title = $r["title"];
$body = $r["body"];
}
$sql->execute();
This brings up an error of 'PDO::query() expects parameter 1 to be string'. This is for the 'if' line.
Have I even written any of that PDO correctly? What would I need to do from here? A friend has recently taught me MySQL, but he doesn't know PDO at all which means I can't ask his advice (not all that helpful...)
This is the correct way, with comments:
try {
//Connect to the database, store the connection as a PDO object into $db.
$db = new PDO("mysql:host=localhost;dbname=database", "user", "password");
//PDO will throw PDOExceptions on errors, this means you don't need to explicitely check for errors.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//PDO will not emulate prepared statements. This solves some edge cases, and relives work from the PDO object.
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
//Prepare the statement.
$statement = $db->prepare("SELECT id, postdate, title, body FROM FooBarTable WHERE id = :id");
//Bind the Value, binding parameters should be used when the same query is run repeatedly with different parameters.
$statement->bindValue(":id", $_GET['id'], PDO::PARAM_INT);
//Execute the query
$statement->execute();
//Fetch all of the results.
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
//$result now contains the entire resultset from the query.
}
//In the case an error occurs, a PDOException will be thrown. We catch it here.
catch (PDOException $e) {
echo "An error has occurred: " . $e->getMessage();
}
You need to use PDOStatement::execute instead of PDO::query:
$foo_query = $sql->execute();
You may also bind all your params at once when calling execute:
$foo_query = $sql->execute(array(
':id' => $id
));
You should change it to:
$sql->execute();
if($r = $sql->fetch()) {
$title = $r["title"];
$body = $r["body"];
Try this:
$sql = $DBH->prepare("SELECT id, postdate, title, body
FROM FooBarTable WHERE id = :id OR id = $id");
$sql->bindParam (':id', $_REQUEST['id'],PDO::PARAM_INT);
$sql->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$title = $row["title"];
$body = $row["body"];
}

Categories