One of the nice things about the PDO way is you can reuse a prepared statement numerous times with different sets of arguments without needing to prepare it again.
I can’t seem to find how to do that with $wpdb – but it is very important to how I code, makes the code a lot simpler.
Sorry, no. The reason for prepare is to prevent SQL injection attacks. If you do not pass the arguments used, there is nothing to prepare. It does not make sense to reuse prepared strings with different arguments because it is the arguments that are being prepared, the static string portions pass through unchanged.
Just because you could do so in the past without throwing a warning does not mean you were doing anything effective for security.
No, it is not the argument that is being prepared, that’s not how prepared statements work.
Prepared statements are a feature of the database, not a feature of the class before the query is sent to the database. If WordPress is doing what you suggest then they aren’t actually prepared statements and the function in the wpdb class is mis-named.
That they are a feature of the database is why prepared statements require the mysqli driver and don’t work with the older mysql driver.
With all due respect, I’m sure we could all discuss code naming semantics from here until Xmas but the bottom line is that, currently, WordPress core mandates that you carry out custom db queries in a very specific way to enhance security. If you don’t follow these rules, then you’ll end up with generated warnings – for good reason.
Longer term, if you feel that you could contribute something to core – including perhaps a better approach for custom db queries that enhances coding performance & security by adopting some elements of PDO, then please do consider getting involved in core development.
Is WPDB actually using prepared statements where it prepares the query with placeholders, binds the parameters, and then executes the parameters – or is it only emulating them?
That’s all in the source code, and pretty easy to find (hint: line 1147). You can see exactly what the prepare() function does.
https://core.trac.ww.wp.xz.cn/browser/tags/3.9.1/src/wp-includes/wp-db.php#L0
Just for anyone else stumbling upon this, $wpdb->prepare() does not create a prepared statement, but rather just escaping values, similar to ye olde mysql_real_escape_string(). As a matter of fact, tracing through the code, you’ll notice it eventually ends up calling mysql(i)_real_escape_string() on each parameter.