I'm moving from MYSQL to PDO. I read the PDO official documentation, but I cannot find the fail on the code.
$name = 'fooUser';
$stmt = $PDO->prepare('SELECT * FROM users WHERE username=:name');
$stmt->bindParam(':name', $name, PDO::PARAM_INT );
$stmt->execute();
This query return me the affected rows, and it shouldn't happen.
Change
$stmt->bindParam(':name', $name, PDO::PARAM_INT );
To
$stmt->bindParam(':name', $name, PDO::PARAM_STR );
you are setting the wrong kind of input!
Related
I always use the same variable for my PDO query statements, for example:
// Query 1
$stmt = $db->prepare("UPDATE table_1 SET name=? WHERE somthing=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->bindValue(2, $something, PDO::PARAM_STR);
$stmt->execute();
// Query 2 (right after the above)
$stmt = $db->prepare("UPDATE table_2 SET another_column=? WHERE id=?");
$stmt->bindValue(1, $another_column, PDO::PARAM_STR);
$stmt->bindValue(2, $id, PDO::PARAM_INT);
$stmt->execute();
I know it is ok for the first lines ($stmt = $db->...), my doubt is about binding values. For example if I forget to bind something in first query will my query use the next binding in second query (or vice versa)? or everything is reset after execute()?
Which one is a better practice?
Using same variable to avoid mistakes (e.g. Always $stmt)
Using different variables
Using different variables makes it easier to debug, however I do this occasionally because it is easier to type-hint a single statement.
my doubt is about binding values.
each db->prepare() returns a brand new \PDOStatement so there is no issue about binding values.
In cases like this, different statements used in the same scope, I choose more specific names for the statements.
So in your case I would name them $stmtUpdTable1 and $stmtUpdTable2 or something along those lines.
Since I can't comment other answers: I think it is unnecessary to unset variables which are no longer used, the garbage collector will do his job. No need to make the code messy
I would prefer to unset $stmt after each query. So I don't have to worry about all the things which you have mentioned above.
// Query 1
$stmt = $db->prepare("UPDATE table_1 SET name=? WHERE somthing=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->bindValue(2, $something, PDO::PARAM_STR);
$stmt->execute();
unset($stmt);
// Query 2 (right after the above)
$stmt = $db->prepare("UPDATE table_2 SET another_column=? WHERE id=?");
$stmt->bindValue(1, $another_column, PDO::PARAM_STR);
$stmt->bindValue(2, $id, PDO::PARAM_INT);
$stmt->execute();
Also its a good practice to unset variable which are not required any more.
For security purposes, I set ATTR_EMULATE_PREPARES option to false.
And in development environment, ATTR_ERRMODE is on ERRMODE_EXCEPTION.
But this code :
// $this->bdd is juste a regular PDO instance with some options
$req = $this->bdd->prepare('INSERT INTO users VALUES(NULL, :login, :passwd, :email, :firstname, :lastname, :role, :token_id, :confirmed, :registration_date, :last_connexion_date)');
$req->bindValue(':login', $login, PDO::PARAM_STR);
$req->bindValue(':passwd', $passwd, PDO::PARAM_STR);
$req->bindValue(':email', $email, PDO::PARAM_STR);
$req->bindValue(':firstname', $firstname, PDO::PARAM_STR);
$req->bindValue(':lastname', $lastname, PDO::PARAM_STR);
$req->bindValue(':role', $role, PDO::PARAM_INT);
$req->bindValue(':token_id', $token_id, PDO::PARAM_INT);
$req->bindValue(':confirmed', $confirmed, PDO::PARAM_BOOL);
$req->bindValue(':registration_date', $registration_date, PDO::PARAM_STR);
$req->bindValue(':last_connexion_date', $last_connexion_date, PDO::PARAM_STR);
return $req->execute() ? true : $req->errorInfo();
just fails silently, with in an errCode to 00000.
While browsing stackoverflow and other platforms, I found some similar bugs related to "truly prepared statement" which can be solved (doesn't work for me). I decided to turn on emulation, and it worked perfectly.
My problem : I want to keep truly prepared statements, and I don't know, what's wrong...
EDIT :
I just change from PDO to MySQLi for test purposes, MySQLi works, PDO don't (and still fails siltenty) here the scripts :
http://pastebin.com/jvjsfFVC
MySQLi always does truly prepared statement
Have the try catch between your code that way if we run into errors we can see the error array instead of blank.
try {
$req = $this->bdd->prepare('INSERT INTO users VALUES(NULL, :login, :passwd, :email, :firstname, :lastname, :role, :token_id, :confirmed, :registration_date, :last_connexion_date)');
$req->bindValue(':login', $login, PDO::PARAM_STR);
$req->bindValue(':passwd', $passwd, PDO::PARAM_STR);
$req->bindValue(':email', $email, PDO::PARAM_STR);
$req->bindValue(':firstname', $firstname, PDO::PARAM_STR);
$req->bindValue(':lastname', $lastname, PDO::PARAM_STR);
$req->bindValue(':role', $role, PDO::PARAM_INT);
$req->bindValue(':token_id', $token_id, PDO::PARAM_INT);
$req->bindValue(':confirmed', $confirmed, PDO::PARAM_BOOL);
$req->bindValue(':registration_date', $registration_date, PDO::PARAM_STR);
$req->bindValue(':last_connexion_date', $last_connexion_date, PDO::PARAM_STR);
$execute = $req->execute();
} catch (PDOException $error) {
print_r($error);
die();
}
I am simply trying to insert the variable from a session into a MySQL database and it causes it to fail. var_dump shows SESSIONS all there. No problem there. Why doesn't this work?
$job = $_SESSION['job'];
$user_id = '1';
$name = 'allie';
$stmt = $mysqli->prepare("INSERT INTO
requests(name,job_info,user_id)
VALUES (?,?,?)");
$stmt->bind_param('sss', $name, $job, $user_id);
$stmt->execute();
see pdo bind_param
your parameter is incorrect:
change this:
$stmt->bind_param('sss', $name, $job, $user_id);
with this:
$stmt->bind_param(1, $name, PDO::PARAM_STR);
$stmt->bind_param(2, $job, PDO::PARAM_STR);
$stmt->bind_param(3, intval($user_id), PDO::PARAM_INT);
I'm trying to update data in a table with a BIT type value in it, like the following :
// $show_contact is either '1' or '0'
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
The problem is, it never changes the value, it remains '1' as set on PHPMyAdmin. I tried different PDO::PARAM_ types without success, everything else is working.
edit full script
$sql = "UPDATE users SET password = :password, address = :address, postal = :postal, city = :city, contact = :contact, show_contact = :scontact WHERE id = :id";
$query = $dbh->prepare($sql);
$query->bindValue(':id', $user->id, PDO::PARAM_INT);
$query->bindValue(':password', md5($password), PDO::PARAM_STR);
$query->bindValue(':address', $address, PDO::PARAM_STR);
$query->bindValue(':postal', $postal, PDO::PARAM_STR);
$query->bindValue(':city', $city, PDO::PARAM_STR);
$query->bindValue(':contact', $contact, PDO::PARAM_STR);
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
$query->execute();
PDO has a bit of a bug where any parameter passed to a query, even when specifically given as PDO::PARAM_INT is treated as a string and enclosed with quotes. READ THIS
The only way to tackle it is to try the following:
$show_contact = (int)$show_contact;
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
I believe that the BIT type is mapped to PDO's PARAM_BOOL. Try using it with strictly boolean input.
$show_contact = (bool) $show_contact; // '0' => FALSE, '1' => TRUE
$query->bindValue(':scontact', $show_contact, PDO::PARAM_BOOL);
My php script that calls a Microsoft SQL Stored Procedure escapes the & (ampersand) symbol (in the database I get & instead of &). Unfortunately I need the plain symbol (not the html entity or anything else). I have tried to work around it but I couldn't get it. I have used both PDO and SQLSRV methods. Does someone knows anyway around this? Thanks a lot.
SQLSRV:
$tsql_callSP = "{call MyStoredProcedure( ?, ?)}";
$values = array(
array($ID, SQLSRV_PARAM_IN),
array($Email, SQLSRV_PARAM_IN)
);
$stmt = sqlsrv_query( $conn, $tsql_callSP, $values);
sqlsrv_execute($stmt);
PDO:
$tsq = "EXECUTE MyStoredProcedure ?,?";
try
{
$stmt = $dbh->prepare($tsq);
$stmt->bindParam(1, $ID, PDO::PARAM_INT);
$stmt->bindParam(2, $Email, PDO::PARAM_STR);
$stmt->execute();
}