I've gotten a little confused with the PDO::prepare functions.
I have something like this
array('user_email'=>'hello#net.com','user_pass'=>'password')
and i'd like to translate it into something like this
INSERT INTO user_info (user_email, user_pass) VALUES (hello#net.com, password)
using parameterized queries with PDO (or mysqli, I'm open to suggestions).
Another idea -
array('uid'=>'10', 'first_name'=>'robert', 'last_name'=>'jones')
array("email", "number")
into
SELECT email, number FROM t1 WHERE uid=10 AND first_name=robert AND last_name=jones
I know the answer lies somewhere with PDO::prepare and call_user_func_array, but I've gotten really confused on how the latter function works, and would appreciate an explanation.
I'm confused, and maybe you are too. Here is a simple example:
$sth = $dbh->prepare('SELECT * FROM table WHERE id = ? AND date = ?');
$sth->execute(array(150, '2009-04-04'));
$data = $sth->fetchAll();
Or:
$sth = $dbh->prepare("INSERT table VALUES(:foo, :bar)");
$sth->bindParam(":foo", $foo);
$sth->bindParam(":bar", $bar);
Or:
$sth = $dbh->prepare("INSERT INTO user_info (user_email, user_pass) VALUES (:email, :pass)");
$sth->execute(array(':email' => 'foo#example.org', ':pass' => '1234'));
Hope this helps!
PDOStatement::execute() works with parameters markers, so you have to construct query before calling PDO::prepare().
You don't have to use call_user_func_array(). PDOStatement::execute() takes associative arrays by default.
$stmt = $pdo->prepare("SELECT fld FROM tbl WHERE fld=:parameter1 AND fld2=:parameter2");
$stmt->execute(array(":parameter1" => "value1", ":parameter2" => "value2"));
...
http://se.php.net/manual/en/pdo.prepare.php
Related
I am preparing mysql configuration settings using class. I am confused about it. I always use bindParam. It also possible to insert using array. I mean, what are the differences between array and bindparam.
eg array
$query = $db->prepare("INSERT INTO users SET
username = :uname,
password = :upass,
email = :umail");
$insert = $query->execute(array(
"upass" => "123456",
"umail" => "user#user.com",
"uname" => "username",
));
if ( $insert ){
$last_id = $db->lastInsertId();
}
eg
$stmt = $this -> db_conn -> prepare("INSERT into users(username, password) VALUES(:uname, :upass)");
$stmt -> bindParam(':uname', $username);
$stmt -> bindParam(':upass', $password);
$stmt -> execute();
Desconsidering the fact that with execute you can't choose the data type (it's always PDO::PARAM_STR) There's only a main difference between both (which is from core). PDOStatement::bindParam is by reference while PDOStatement::execute isn't. PDOStatement::execute do internnaly the same thing as PDOStatement::bindValue, but twice.
Internally (in C), bindValue calls the same method which execute calls. The method name which is called is really_register_bound_param.
On the other hand, bindParam calls other method called register_bound_param.
It means that bindValue calls the same method called by execute more than one time while bindParam calls a method to bind as a reference and only "really register" the param when execute is called.
Thinking about bind by reference, it's only possible using bindParam:
//fictional code
$stmt= $pdo->prepare("INSERT INTO table (column) VALUES (:value)");
$stmt->bindParam(":value", $randomValue);
for($i = 0 ; $i < 1000; $i))
{ $randomValue = rand(1000,1000000);
$stmt->execute();
}
Is it worthy? Perhaps while a while with a complex insert with multiples parameters could reduce the overhead with rebinding a new parameter or a big amount of them.
Ok so I am in a confusion here. I have seen multiple queries like these.
Query 1
$stmt = "SELECT * FROM tablename WHERE user = :user";
$stmt = $pdo->prepare($stmt);
$stmt-> bindValue(':user', $user);
$stmt-> execute();
Query 2
$stmt = $pdo->prepare("SELECT * FROM tablename WHERE user = :user");
$stmt-> execute(['user' => $user]);
So, I want to know which of the above queries are most efficient and preferred while coding? Or is there any other better way than these to code in PDO?
It is not bindParam/bindValue that makes your query safe but :user thing that is called parameter or placeholder. As long as you have all variables in your query substituted with parameters, your query is 100% safe.
So you can tell that the second option is as safe as the fiirst one, though being more concise. Personally, I'd prefer positional placeholders that makes even more concise code:
$stmt = $pdo->prepare("SELECT * FROM tablename WHERE user = ?");
$stmt-> execute([$user]);
but all there variants are equally safe and only a matter of taste.
I'm new to PDO, in fact, this is the first time that I'm using it. All the while I've been using mysql which is depreciated. And so recently, I'm trying to update all my site to use PDO which is better and safer according to many sources that I found from the internet.
However, those tutorials is making me even more curious and full of questions. I've been google for the whole day and I still can't get the best answer or examples.
Let's start by this code below,
// query
$sql = "SELECT title FROM books ORDER BY title";
$q = $conn->query($sql);
$q->setFetchMode(PDO::FETCH_ASSOC);
// fetch
while($r = $q->fetch()){
print_r($r);
}
I do understand that it fetches the data just like mysql_fetch_assoc. But, here's another code that I found from the net.
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
and lastly, this:
$stm = $pdo->prepare('SELECT * FROM table LIMIT ?, ?');
$stm->bindParam(1, $limit_from,PDO::PARAM_INT);
$stm->bindParam(2, $per_page,PDO::PARAM_INT);
$stm->execute();
$data = $stm->fetchAll();
Why are there so many different methods to fetch a data ?
I somehow found out that with bindParam, you're able to set integer or strings for the variable? But with this below...
$pdo->execute(array(':col2' => $col2, ':col3' => $col3, ':col4' => $col4));
Am I still able to mix integer and strings without declaring if it's integer or strings?
Is it ok if I do like this ? mixing strings and integer in execute array...
$sql = "INSERT INTO books (id,author) VALUES (:id,:author)";
$q = $conn->prepare($sql);
$q->execute(array(':author'=>'string', ':id'=>1));
And also, does all codes above avoid SQL injection ?
I somehow prefer the execute array method as it is shorter and I don't want to declare if it's integer or strings every time like using the bindParam method.
I'm trying to use good PDO as always and almost everything works but one query:
$primary = 'my_id';
$table = 'my_table';
// This or...
$statement = $this->conn->prepare("SELECT MAX(:id) AS id FROM :table");
$statement->bindParam(':id', $primary, PDO::PARAM_STR);
$statement->bindParam(':table', $table, PDO::PARAM_STR);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
// This one. Both doesn't work.
$statement = $this->conn->prepare("SELECT MAX(:id) AS id FROM :table");
$statement->setFetchMode(PDO::FETCH_ASSOC);
$arr = array(
':id' => 'my_id',
':table' => 'my_table',
);
$statement->execute($arr);
These just return a null array. I feel so confused. So I have tried that:
$statement = $this->conn->prepare("SELECT MAX(".$primary.") AS id FROM ".$table);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
And it works. I feel like I'm missing something but can't figure it out. So clearly there's a problem with binding I tried different variations such as writing one of the variable manually, but no luck so far.
Thanks in advance for any help...
You can't use parameters as table names in PDO, so you will have to change this to avoid that. This is not a limitation of PDO, but a limitation of MySQL directly. The manual states that
Parameter markers can be used only where data values should appear,
not for SQL keywords, identifiers, and so forth.
Table and column names are identifiers, so using placeholders for them is not supported. See this question for an alternative method.
I am using named placeholders like so:
$job['services_flag'] = 0;
$SQL = "INSERT INTO jobs (
services_flag
)
VALUES (
:services_flag
)";
$STH = $DBH->prepare($SQL);
$STH->execute($job);
However, this insists on inserting 1.
If I don't use named placeholders:
$SQL = "INSERT INTO jobs (
services_flag
)
VALUES (
0
)";
$STH = $DBH->prepare($SQL);
$STH->execute();
Then it inserts 0. Eh?
Update:
The data type of the services_flag field in my SQL database is BIT. I don't know if that makes any difference.
This is a known bug with BIT type, you should use bindParam for it
You need to bind a value to it:
$STH->bindValue(':services_flag', $job['services_flag']);
$STH->execute();
That's one way to do it. I've seen an array with values mapped to placeholders passed in the execute() as well.