I have the following PHP code doing a very simple select into a table.
$statement = $db->prepare("SELECT * FROM account WHERE fbid = :fbid");
$statement->bindParam(":fbid",$uid, PDO::PARAM_STR,45);
$out = $statement->execute();
print_r($out) // 1;
//$out = $statement->execute(array(':fbid' => $uid)); // also doesn't work
$row = $statement->fetch();
$out is true (success) yet $row is null.
EDIT:
$statement->debugDumpParams();
Outputs
SQL: [40] SELECT * FROM account WHERE fbid = :fbid Params: 1 Key: Name: [5] :fbid paramno=-1 name=[5] ":fbid" is_param=1 param_type=2
If I modify the code as follows:
$statement = $db->prepare("SELECT * FROM account WHERE fbid = $uid");
$out = $statement->execute();
$row = $statement->fetch();
$row contains the record I'm expecting.
I'm at a loss. I'm using the PDO::prepare(), bindParams() etc to protect against SQL Injection (maybe I'm mistaken on that).
EDIT:
In my example, $uid is a numerical string (ie a string containing only numbers). In the database, the column type is VARCHAR(45)
EDIT:
If I change the database type from VARCHAR(45) to BIGINT, both queries work. If I change the type in the database type back to VARCHAR(45) again, it works. So what gives?
Please halp.
You need to check your fbid value. it should be always string if its integer value is greater than 2^32 (unsigned), simply cast by (string)$uid is not work, and sprintf("%.0f",...) will only works when integer value less than 2^52, because on 32-bit OS when a number is greater than 2^31(32 unsigned) PHP will assume it is double type and default precise is only 14 decimal but fbid is 20.
You have to keep fbid in string contains only [0-9] in PHP, doesn't matter it is stored as BIGINT or VARCHAR in MySQL, MySQL accepts only string sql statement and always returns result in string format.
$mi = new mysqli("localhost", "root", "xxx", "test");
$uid = "12379739851403943597"; // Works
//$uid = 12379739851403943597; // never Works
//$uid = (string) 12379739851403943597; // get "1.2379739851404E+19" wrong string !
//$suid = sprintf("%.0f", $uid); // get "12379739851403943936" lost precise
$stmt = $mi->prepare("select * from bitest where id = ?");
$stmt->bind_param('s', $uid);
$stmt->execute();
$stmt->bind_result($id, $name);
$stmt->store_result();
print "numrow: " . $stmt->num_rows . " - \n";
$stmt->fetch();
print "$id - $name \n";
$stmt->free_result();
$stmt->close();
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'xxx');
$sql = "select * from bitest where id = ?";
$sth = $pdo->prepare($sql);
$sth->bindParam(1, $uid, PDO::PARAM_STR);
$sth->execute();
var_dump($sth->fetchAll(PDO::FETCH_ASSOC));
I think there may be an issue with your PDO installation.
$uid = 552192373; // my facebook uid for testing
$statement = $db->prepare("SELECT * FROM users WHERE facebook_uid = :fbid");
$statement->bindParam(":fbid",$uid, PDO::PARAM_STR,45);
$out = $statement->execute();
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo '<pre>';
print_r($row);
echo '</pre>';
returns:
Array
(
[id] => 1
[facebook_name] => Jason Boehm
[facebook_uid] => 552192373
)
It's been a while... try passing a hash to execute instead:
$statement->execute(array( 'fbid' => $uid ));
Maybe try PDO::PARAM_INT
Aside from that, keep in mind bindParam() takes the variable as a reference. Maybe your demo code doesn't show you changing the value of that variable before execute() is called. See bindValue() if needed.
Try dropping the extra parameter,
$statement->bindParam (":fbid", $uid, PDO::PARAM_STR);
(edit)
Are you 100% positive there is no extra whitespace surrounding the UID? Test with trim() and pass by value:
$statement->bindValue (":fbid", trim($uid), PDO::PARAM_STR);
Related
I noticed that if you open a connection with PDO :: SQLSRV_ATTR_ENCODING = PDO :: SQLSRV_ENCODING_UTF8 (default configuration) there is a problem when using LIKE with named parameters on char fields.
No automatic trim of the padding spaces is performed, an operation that is performed in all other cases.
How to reproduce the problem:
Create a table and insert data in it:
CREATE TABLE testDB.dbo.TEST_TABLE (
ID_FIELD int IDENTITY(1,1) NOT NULL,
CHAR_FIELD char(15) COLLATE Latin1_General_CI_AS DEFAULT ' ' NOT NULL
CONSTRAINT TEST_TABLEK00 PRIMARY KEY (ID_FIELD)
);
INSERT INTO TEST_TABLE (CHAR_FIELD) VALUES ('Test data'), ('MyString'), ('My data 123');
Then on PHP I get this results
$options = array();
$pdo = new PDO("sqlsrv:Server=testServer;Database=testDB", 'test', 'test', $options);
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD = 'Test data'");
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 1 row
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD LIKE 'Test data'");
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 1 row
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD = :CHAR_FIELD");
$value = 'Test data';
$stmt->bindParam('CHAR_FIELD', $value, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 1 row
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD LIKE :CHAR_FIELD");
$value = 'Test data';
$stmt->bindParam('CHAR_FIELD', $value, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 0 rows
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD LIKE :CHAR_FIELD");
$value = 'Test data ';
$stmt->bindParam('CHAR_FIELD', $value, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 1 row
$options = array(PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_SYSTEM);
$pdo = new PDO("sqlsrv:Server=testServer;Database=testDB", 'test', 'test', $options);
$stmt = $pdo->prepare("SELECT * FROM TEST_TABLE WHERE CHAR_FIELD LIKE :CHAR_FIELD");
$value = 'Test data';
$stmt->bindParam('CHAR_FIELD', $value, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(); //Returns 1 row
The behavior of the like together with the named parameter, when opening the connection to the DB in UTF8, is not uniform with all the other behaviors.
Only in that case is the field not automatically trimmed while in all other cases it is. Personally, it seems to me more of a bug than a deliberate behavior.
I find myself managing a huge application, developed over 10 years and which can interface with different databases (mysql, postgres, oracle and sqlserver).
Changing the queries one by one is impossible, I would need a solution at the configuration level (some flags to set in the PDO or on SqlSever itself) or at least find a way to normalize this behavior to all the others automatically via code.
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.
I have a stored procedure in SQL Server 2014 that takes two integers as input and returns an integer. Below is the code to create the stored procedure:
CREATE PROCEDURE [dbo].[p_MergePerson_AuditLog_CheckLogForDuplicate]
#Person1_ID INT,
#Person2_ID INT,
#RowCount INT OUTPUT
AS
SET NOCOUNT ON
SELECT
#RowCount = COUNT(mpal.Transaction_ID)
FROM
MergePersonAuditLog mpal
WHERE
#Person1_ID = #Person2_ID
AND #Person2_ID = #Person1_ID
RETURN #RowCount
Basically, it just takes two ids and sees if a comparison has been made before, just in a different order. Below is the PHP code:
// Connecting to DB
try {
$conn = new PDO("sqlsrv:server=IP;Database=DB", "user", "pwd");
}
catch(PDOException $e) {
die("Error connecting to server $e");
}
// Arrays that will hold people IDs
$person1Array = array();
$person2Array = array();
// Holds the row count used to see if a comparison has already been performed
$rowcount = 5; // Setting to 5 to make sure the stored procedure is actually setting the value.
// Query to get the people that will be compared
$query = "SELECT p.PersonID
FROM Person p
WHERE (p.StudentNumber IS NULL OR p.StudentNumber = '')
AND (p.StaffNumber IS NULL OR p.StaffNumber = '')
ORDER BY
p.PersonID";
$stmt = $conn->query($query);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $key => $value) {
$person1Array[] = $value;
}
}
$person2Array = $person1Array;
// Begin the comparisons
print "Beginning the comparisons <br>";
foreach ($person1Array as $person1id) {
foreach ($person2Array as $person2id) {
print "Checking $person1id and $person2id <br>";
if ($person1id != $person2id) {
print "Not the same. Continuing.<br>";
// Checking to see if the comparison has already been made
$query = "{? = call p_MergePerson_AuditLog_CheckLogForDuplicate(?, ?)}";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $rowcount, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT,4);
$stmt->bindParam(2, $person1id, PDO::PARAM_INT);
$stmt->bindParam(3, $person2id, PDO::PARAM_INT);
$stmt->execute();
print $rowcount . "<br>";
}
}
}
print "FINISHED! <br>";
$stmt = null;
$conn = null;
?>
When I run this code, 5 is still being printed for $rowcount even though it should be set to 0 by the stored procedure. If the value is 0, more code will be executed that I didn't include, but I want to get this part right first. Running the procedure in management studio works fine. Can someone tell me why $rowcount is not getting updated? I am running php 5.6 on Windows 10.
Ok, I found an answer that worked for me. I read https://msdn.microsoft.com/en-us/library/cc626303(v=sql.105).aspx which doesn't have anything to do with PDO_SQLSRV, but with sqlsrv_connect(). In that article, it stated the last parameter was the output parameter. I changed my code to look like this:
// Checking to see if the comparison has already been made
$query = "{call p_MergePerson_AuditLog_CheckLogForDuplicate(?, ?, ?)}";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $person1id, PDO::PARAM_INT);
$stmt->bindParam(2, $person2id, PDO::PARAM_INT);
$stmt->bindParam(3, $rowcount, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT,4);
$stmt->execute();
print $rowcount . "\n";
Basically, I moved the "?" From the beginning of the call statement to the end and moved the bindParam to the end as well. That seems to have done the trick.
You could get the return value via a select statement:
$query = "select p_MergePerson_AuditLog_CheckLogForDuplicate(?, ?)";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $person1id, PDO::PARAM_INT);
$stmt->bindParam(2, $person2id, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchColumn();
I used to do :
$resource = mysql_query("SELECT * FROM table WHERE id = " . $id);
$user = mysql_fetch_assoc($resource);
echo "Hello User, your number is" . $user['number'];
I read that mysql statements are all deprecated and should not be used.
How can i do this with PDO?
The first line would be :
$stmt = $db->prepare("SELECT * FROM table WHERE id = " . $id); // there was an aditional double quote in here.
$stmt->execute(array(':id' => $id));
What about the mysql_fetch_assoc() function?
I am using php
You can use (PDO::FETCH_ASSOC) constant
Usage will be
while ($res = $stmt->fetch(PDO::FETCH_ASSOC)){
....
}
Here's the reference (documentation precisely) : http://www.php.net/manual/en/pdostatement.fetch.php
All well documentned in the manual: http://php.net/manual/en/pdostatement.fetchall.php
As example:
<?php
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* Fetch all of the remaining rows in the result set */
print("Fetch all of the remaining rows in the result set:\n");
$result = $sth->fetchAll();
print_r($result);
?>
There is a nice manual right here.
From which you can learn what you don't need to set fetch mode explicitly with every fetch.
...and even what with PDO you don't need no arrays at all to echo a number:
$stmt = $db->prepare("SELECT number FROM table WHERE id = ?");
$stmt->execute(array($id));
echo "Hello User, your number is".$stmt->fetchColumn();
This is a nice tutorial:
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
$stmt = $db->query("SELECT * FROM table");
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($results);
?>
You can use PDO::FETCH_ASSOC for the same.
$stmt = $db->prepare("SELECT * FROM table WHERE id = :id");
$stmt->execute(array(':id' => $id));
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
while($record = $stmt->fetch()) {
//do something
}
You can find a good tutorial here
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 />";
}