15

I'm building a database object that joins the PDO object with the PDOStatement object in order for chaining to be available. Basically I just put the methods I most frequently use, but bindParam is giving me a hard time.

private $stmt = null;

...

public function prepare($statement,array $driver_options = array()) {
    if($this->stmt) throw new \Exception('PDO Statement already prepared, no override!');
    $this->stmt = parent::prepare($statement, $driver_options);
    return $this;
}

public function bindParam($place, &$val, $dataType){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->bindParam($place, $val, $dataType);
    return $this;
}

public function execute(array $params = array()){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->execute($params);
    return $this;
}

public function fetchAll($pdoFetchType){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    return $this->stmt->fetchAll($pdoFetchType);
}

...

public function getStmt(){
    return $this->stmt;
}

public function clearStmt(){
    $this->stmt = null;
}

I get the error, from the title, in this code:

$i = 0;
$db->prepare('SELECT * FROM users LIMIT ?,1')->bindParam(1, $i, \PDO::PARAM_INT);
while($row = $db->execute()->fetchAll(\PDO::FETCH_ASSOC)){
    echo "<pre>".print_r($row, true)."</pre>";
    $i++;
}

Basically what I found out about this error is that it occurs when provided variables in bindParam are null, but $i is clearly not null. Can you help me out?

EDIT: Also running

var_dump($this->stmt->bindParam($place, $val, $dataType));

in the bindParam method returns TRUE. From the manual:

Return Values

Returns TRUE on success or FALSE on failure.

It's succeeding but not binding the parameter ??? I feel my brain is going to explode soon.

6
  • What happens if you put var_dump($val) inside the your defined bindParam()? And if you put var_dump($this->stmt)? Commented Dec 7, 2013 at 2:34
  • @FranciscoPresencia int(0) object(PDOStatement)#6 (1) { ["queryString"]=> string(29) "SELECT * FROM users LIMIT ?,1" } I really hate it when php does that to me.. Commented Dec 7, 2013 at 2:38
  • I'm running out of ideas, try bindValue() instead of bindParam() inside of your function public function bindParam to see if something changes. From the doc, Unlike PDOStatement::bindValue(), the variable is bound as a reference and will only be evaluated at the time that PDOStatement::execute() is called. but I'm not sure if it'd change anything. Commented Dec 7, 2013 at 2:46
  • @FranciscoPresencia even the error message stayed the same, at least that could've changed.. Q_Q Commented Dec 7, 2013 at 2:50
  • The debugger is your friend. Commented Dec 7, 2013 at 3:03

2 Answers 2

13

I guess using a reference &$val instead of a value $val is what causes the issue.

Please try this code instead:

public function bindParam($place, $val, $dataType)
{
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->bindParam($place, $val, $dataType);
    return $this;
}

EDIT

My above answer is wrong.

Try modifying the execute method:

public function execute(array $params = array()){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->execute();
    return $this;
}

Passing an empty array as parametre to the execute method removes all previous bindings. This is why bindParam returned true (successfully bound), yet the "no params were bound" error appeared as soon as you called execute.

Sign up to request clarification or add additional context in comments.

6 Comments

It used to be without a reference, still got the same error. I added the reference because without it, wrapping the parent bindParam like this just makes no sense
References are dangerous and it's easy to break things. Please try running your loop and calling bindParam in each iteration with the updated $i value instead of relying on the reference. I'm sure it will work as expected.
It doesn't. And references aren't dangerous when they're used right. If the original PDO function bindParam uses a reference, then there must be a good reason for that, as there is. I tried what you suggested anyway and, sadly, the error is the same.
I hereby retire my claims regarding your supposed reference misuse - see my edited answer.
One of these things that makes you wanna go "How in the H did I not see this". Thank you very much sir!
|
7

Got the same error, but different cause

My request had comments, one of which included a damn question mark.
For PDO, a "?" is, of course, a parameter to bind.

My request had no issue anywhere else, and I had no idea where PDO would invent a "parameter" while I wasn't using any, since I always use named placeholders, like :value


Spent more than one hour on this :(
May this answer help some people having this foolishly trivial issue.

1 Comment

Oh, nice catch - thank you! Had the same issue with Yii 1.1 on upgrading the server to PHP7.2 and MySQL 5.7.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.