是否可以从PDO准备语句中获取参数名称

I have a prepared query, say

SELECT * FROM userSignLog WHERE userID = :uid AND userStatus = :status

Where, value for :uid and :status will be passed along with other values in my $_POST array.

Now, i want to pass (or Bind) only :uid and :status for my current query, dynamically. I was iterating through the entire $_POST array, taking the $_POST[name] as parameter name and bind the declared parameter with value of $_POST[name].

While executing, PHP throws below error:

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

If i can somehow manage to get the List of Token names from the prepared statement, i can take only those values from my POST array, bind and execute the query. I am willing to know if it is possible to get the list from a prepared statement?

You could, possibly capture the output of PDOStatement::debugDumpParams(). There is an example of the output on the linked page.

For example:-

$sql = "SELECT * FROM userSignLog WHERE userID = :uid AND userStatus = :status";
$statement = $db->prepare($sql);
$uid = 'testUid';
$status = 'testStatus';
$statement->bindParam('uid', $uid);
$statement->bindParam('status', $status);
ob_start();
$statement->debugDumpParams();
$params = ob_get_clean();
var_dump($params);

Gives the following output:-

string 'SQL: [70] SELECT * FROM userSignLog WHERE userID = :uid AND userStatus = :status
Params:  2
Key: Name: [4] :uid
paramno=-1
name=[4] ":uid"
is_param=1
param_type=2
Key: Name: [7] :status
paramno=-1
name=[7] ":status"
is_param=1
param_type=2
' (length=240)

The information you want is in there, it is just a matter of digging it out.

I'm not sure how effective this would be, although it is the only reference I can find to the information you are looking to access.

As PDO supports an OOP style interface you are free to overwrite the PDOStatement class, espcially the methods bindValue and exec in order to generate that info. Also you would add a method getParams().

To make PDO use your custom statement class you need to issue:

$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('CustomStatement', array($pdo)));