I have a very simple helper function to produce SET statement for traditional plain mysql driver usage:
function dbSet($fields) {
$set='';
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
}
}
return substr($set, 0, -2);
}
used like this
$id = intval($_POST['id']);
$fields = explode(" ","name surname lastname address zip fax phone");
$_POST['date'] = $_POST['y']."-".$_POST['m']."-".$_POST['d'];
$query = "UPDATE $table SET ".dbSet($fields)." stamp=NOW() WHERE id=$id";
it makes code quite DRY and easy but flexible at the same time.
I gotta ask if anyone willing to share a similar function, utilizing PDO prepared statements feature?
I am still in doubts, how to accomplish this.
Is there a straight and simple way to use PDO prepared statements to insert data?
What form it should be? Query builder helper? Or insert query helper? What parameters it should take?
I hope it can be easy enough to be used as an answer here on SO. Because in the every topic we can see prepared statements usage recommendation, but there is not a single good example. Real life example, I mean. To type bind_param() 20 times is not a good programming style I believe. And even 20 question marks too.
Like others I've extended the standard PDO class to suit my needs. Something along the lines of this may suit you:
Then you can use it quite simply:
Thanks to everyone.
Every answer was helpful and I wish I could split the bounty.
At the end, to my surprise, I was able to make it the same way as before, based on on accepted answer
It can be wrapped into a helper function, but I doubt there is necessity. It will shorten the code by just one line.
pdoSet code:
I usually have a class extending PDO, but my class is pretty custom. If I get it cleaned up and tested I will post it at a later time. Here is a solution to your system, however.
This may not be perfect and could use tweaking. It takes into account that
$dbh
is setup with a PDO Connection. Pending any minor syntax issues I made, that should work.EDIT
Really though, I think I would go for Doctrine ORM (or another ORM). As you setup the model and add all the validation there, then it is as simple as:
That should populate the contents easily. This is of course with an ORM, like Doctrine.
UPDATED
Did some minor tweaks to the first code, such as putting
isset
back and usingrtrim
oversubstr
. Going to work on providing a mock up of a PDO Extension class just gotta layout the way to do it and do some unit tests to make sure it works.i would extend the Core PDO Class andd a method like so:
Then use like so
But as its already been said that you should be VERY weary of what your trying to do, you need to validate your data, its been sanitized but you not validated.
Even though my DB class does not use prepared statements I still want to mention it here. I see no reason at all to implement everything with prepared statements. I do know that prepared statements are faster, but only when used multiple times. If you execute the query only once (and this is the only type of query I normally need to use), it is slower. Thus it is counterproductive to use prepared statements everywhere.
Proper description of the class may be found some place else at stackoverflow. But here some of the good stuff:
DB::x
forDB::instance()->execute
andDB::q
forDB::instance()->query
?
and?x
(wherex
may be,
,&
and|
). The?,
placeholder may be used as an UPDATE helper here.But for full information see the stackoverflow post linked above ;)
PS: The README in the repo does not apply to this class. It is for the normal
DB.php
, not forDB_intelligent.php
. PPS: The class is written for PHP 5.3. If you want to use it on PHP 5.2 simply copy all those PDO methods fromDB_forPHP52.php
toDB_intelligent.php
and remove the__callStatic
method.Insert queries often require many placeholders. The question mark style is then hard to read, and named parameters are repetitive and prone to typing errors. So, I created a function for the whole insert query:
Usage is simple:
And if you need
lastInsertId()
: