Because it works this way.
it throws an error not at bind but at execute. That's all.
So, there is no need in loop and you can make your method way shorter.
public function executeSelect($sql, $bindings = FALSE)
{
$stmt = $this->dbPDO->prepare($sql);
$stmt->execute($bindings);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
There is no need in checking execute result either, I believe.
In case of error it will raise an exception already.
By the way, I'd make several helper functions based on this one, returning scalar value and single row. They are mighty helpful. Though I find named placeholders a bit dull. Compare this code:
$name = $db->getOne("SELECT name FROM users WHERE group=?i AND id=?i",$group,$id);
vs.
$sql = "SELECT name FROM users WHERE group=:group AND id=:id";
$name = $db->getOne($sql,array('group' => $group, 'id' => $id));
named require 2 times more code than anonymous.
A perfect example of WET
acronym - "Write Everything Twice"