Why am I receiving a PDO query error? - php

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"];
}

Related

PDO WHERE Condition Refuses to Fetch Rows

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'"

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

mysql pdo hit counter

I can't make the counter add 1 into the DB and the value increment every time when somebody go to the page... only works when is reloaded.
Where is the error in my code? Can you help me with this issue?
I don't know if you need my entire html page, if you want I page it. the url have the id is show like this: post.php?id_blog=4
THe code:
<?php
try {
$query = "SELECT id_blog, blog_titulo, blog, vistoblog FROM BLOG WHERE id_blog = ?";
$stmt = $conn->prepare( $query );
$stmt->bindParam(1, $_REQUEST['id_blog']);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$id_blog = $row['id_blog'];
$blog_titulo = $row['blog_titulo'];
$blog = $row['blog'];
$vistoblog = $row['vistoblog'];
}catch(PDOException $exception){
echo "Error: " . $exception->getMessage();
}
try{
$visto = $vistoblog + 1;
$sql = "UPDATE BLOG SET
vistoblog = :vistoblog
WHERE id_blog = :id_blog";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':vistoblog', $visto, PDO::PARAM_STR);
$stmt->bindParam(':id_blog', $id_blog, PDO::PARAM_INT);
$stmt->execute();
}catch(PDOException $exception){
echo "Error: " . $exception->getMessage();
}
?>
I recommend making your SQL just like this:
UPDATE BLOG SET
vistoblog = vistoblog + 1
WHERE id_blog = :id_blog
The reason is to avoid a race condition. What if two people visit the page simultaneously, and both PHP threads read vistoblog value 123, add 1, and both try to increment it to value 124?
By using the expression above, you don't have to read the current value, and you avoid the chance of a race condition like that.

PHP PDO using try

For best practices should I be putting the fetch command portion inside of the try statement or is the prepare and execute sufficient?
$sql = "SELECT * FROM links WHERE device = 'mobile' AND category = ? ORDER BY category asc, link_id asc";
try{
$sth = $dbh->prepare($sql);
$sth->bindValue(1, $cat, PDO::PARAM_STR);
$sth->execute();
}
catch(\PDOException $ex){
print($ex->getMessage());
}
if($sth->rowCount()) {
print("<a data-rel=\"dialog\" data-transition=\"pop\" href=\"index.php?action=addnew&cat=$cat\">Add New Menu Item</a><br/><br/>");
print("<ul data-role=\"listview\" data-filter=\"true\">");
while($row = $sth->fetch(PDO::FETCH_BOTH)) {
print("<li>");
print("<a data-transition='fade' href='$row[$COL_HREF]'>$row[$COL_LINK_NAME]<br/></a>");
print("</li>\n");
}
print("</ul>");
}
Inside the try with the rest of the code.
If the code in your try produces an Exception, you're printing out the exception message but are then continuing to check the rowCount(), which is dependent on $sth being successfully set and executed.

How can I properly use a PDO object for a parameterized SELECT query

I've tried following the PHP.net instructions for doing SELECT queries but I am not sure the best way to go about doing this.
I would like to use a parameterized SELECT query, if possible, to return the ID in a table where the name field matches the parameter. This should return one ID because it will be unique.
I would then like to use that ID for an INSERT into another table, so I will need to determine if it was successful or not.
I also read that you can prepare the queries for reuse but I wasn't sure how this helps.
You select data like this:
$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator
You insert in the same way:
$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));
I recommend that you configure PDO to throw exceptions upon error. You would then get a PDOException if any of the queries fail - No need to check explicitly. To turn on exceptions, call this just after you've created the $db object:
$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
I've been working with PDO lately and the answer above is completely right, but I just wanted to document that the following works as well.
$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();
You can use the bindParam or bindValue methods to help prepare your statement.
It makes things more clear on first sight instead of doing $check->execute(array(':name' => $name)); Especially if you are binding multiple values/variables.
Check the clear, easy to read example below:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetch(PDO::FETCH_ASSOC);
$row_id = $check['id'];
// do something
}
If you are expecting multiple rows remove the LIMIT 1 and change the fetch method into fetchAll:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetchAll(PDO::FETCH_ASSOC);
//$check will now hold an array of returned rows.
//let's say we need the second result, i.e. index of 1
$row_id = $check[1]['id'];
// do something
}
A litle bit complete answer is here with all ready for use:
$sql = "SELECT `username` FROM `users` WHERE `id` = :id";
$q = $dbh->prepare($sql);
$q->execute(array(':id' => "4"));
$done= $q->fetch();
echo $done[0];
Here $dbh is PDO db connecter, and based on id from table users we've get the username using fetch();
I hope this help someone, Enjoy!
Method 1:USE PDO query method
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
Getting Row Count
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';
Method 2: Statements With Parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Method 3:Bind parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Want to know more look at this link
if you are using inline coding in single page and not using oops than go with this full example, it will sure help
//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw);
//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";
//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);
//view the entire array (for testing)
print_r($result);
//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

Categories