views:

125

answers:

2

Hello,

I've come upon a rather interesting thing, which I can't seem to figure out myself. Everytime when executing a SQL statement which contains a '... AND ...' the result is empty.

Example:

echo('I have a user: ' . $email . $wachtwoord . '<br>');

$dbh = new PDO($dsn, $user, $password);

$sql = 'SELECT * FROM user WHERE email = :email AND wachtwoord= :wachtwoord';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(:email,$email,PDO::PARAM_STR);
$stmt->bindParam(:wachtwoord,$wachtwoord,PDO::PARAM_STR);

$stmt->execute();

while($row = $stmt->fetchObject())
{   
  echo($row->email . ',' . $row->wachtwoord);
  $user[] = array(
    'email' => $row->email,
    'wachtwoord' => $row->wachtwoord
  );
}

The first echo displays the correct values, however the line with

echo($row->email . ',' . $row->wachtwoord);

is never reached. A few things I want to add: 1) I am connected to the database since other queries work, only the ones where I add an 'AND' after my 'WHERE's fail. 2) Working with the while works perfectly with queries that do not contain '... AND ...' 3) Error reporting is on, PDO gives no exceptions on my query (or anything else) 4) Executing the query directly on the database does give what I want:

SELECT * FROM user WHERE email = '[email protected]' AND wachtwoord = 'jurgen'

I can stare at it all day long again (which I already did once, but I managed to work around the 'AND'), but maybe one of you can give me a helping hand.

Thank you in advance.

Jurgen

A: 

Let's see if one of those debug queries

....
$dbh = new PDO($dsn, $user, $password);

function debugQuery($dbh, $querystring, $params) {
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
  $stmt = $dbh->prepare($querystring);
  $stmt->execute($params);
  echo $querystring, ":<br />\n";
  while ( false!== ($row=$stmt->fetch(PDO::FETCH_ASSOC)) ) {
    echo '  ', join(', ', $row), "<br />\n";
  }
}

debugQuery($dbh, 'SELECT Count(*) as c FROM user', array());
debugQuery($dbh, 'SELECT Count(*) as c FROM user WHERE email=?', array($email));
debugQuery($dbh, 'SELECT Count(*) as c FROM user WHERE wachtwoord=?', array($wachtwoord));
debugQuery($dbh, 'SELECT Count(*) as c FROM user WHERE email=? AND wachtwoord=?', array($email, $wachtwoord));
debugQuery($dbh, 'SELECT Count(*) as c FROM user WHERE email LIKE ? AND wachtwoord LIKE ?', array( '%'.trim($email).'%', '%'.trim($wachtwoord).'%'));

$sql = 'SELECT * FROM user WHERE email = :email AND wachtwoord= :wachtwoord';
$stmt = $dbh->prepare($sql);
...

returns something interesting.

edit: Doesn't seem so... then let's attack this from another angle

$email = 'emailA';
$wachtwoord = 'wachtwoordA';
echo('I have a user: ' . $email . $wachtwoord . '<br>');

//$dbh = new PDO($dsn, $user, $password);
$dbh = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly'); 
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// create a temporary table
$dbh->exec('CREATE TEMPORARY TABLE tmp_user ( id int auto_increment, email varchar(32), wachtwoord varchar(32), primary key(id))');
// and fill in exactly the record we're looking for
$dbh->exec("INSERT INTO  tmp_user (email, wachtwoord) VALUES ('$email', '$wachtwoord')");


$sql = 'SELECT * FROM tmp_user WHERE email = :email AND wachtwoord= :wachtwoord';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':email', $email,PDO::PARAM_STR);
$stmt->bindParam(':wachtwoord', $wachtwoord,PDO::PARAM_STR);

$stmt->execute();

while($row = $stmt->fetchObject())
{   
  echo($row->email . ',' . $row->wachtwoord);
  $user[] = array(
    'email' => $row->email,
    'wachtwoord' => $row->wachtwoord
  );
}

prints I have a user: emailAwachtwoordA<br>emailA,wachtwoordA on my version of php/mysql.

VolkerK
11111---Which is exactly what I expect it to do, since I have only one record.Guess I'll have to make a new function for these SELECT statements then.However I keep finding it strange my version doesn't work on queries without an 'AND' in it and does work on queries with one simple 'WHERE'.Thank you for your help, VolkerK.
Jurgen
next try.......
VolkerK
I have a user: emailAwachtwoordA<br>emailA,wachtwoordA --- The same result here. The code you now use is so close to what I was trying myself, although yours is not failing, mine was. I can't believe making a temp table is really necessary?
Jurgen
No, it isn't. I only used it so it doesn't alter any of your permanent data. And that the demo script is so close to your code was intentional ;-) Something's different on your side. Something that is not included in the code snippet you've posted in the question. The only purpose of the demo is to show that it _is_ possible.
VolkerK
I've found the problem. I noticed your comment above and went over a piece of code that was intentionally left out in my first post. As often, the problem was in that piece of code. To make my params easier, I made another array for them which I then read through and added as a param per element. The problem was that the array didn't add the params as I expected. Therefor the SQL query was correct at first sight, but the params where not. Now I only need to find how to make that array work, or just abandon the idea and continue with what we both thought of. You did help a lot. Thank you again.
Jurgen
You could simply pass the array to $stmt->execute($params). If you use unnamed placeholders in the statement `VALUES(?,?,?)` the parameters will be used in the order as they appear in the array (like in foreach). If you have named parameters `VALUES(:a,:b,:c)` the array has to have those keys (like e.g. `$params=array(':a'=>'lalala', ':b'=>1, 'c:'=>99)`)
VolkerK
A: 
while($row = $stmt->fetchObject()){}

Shouldn't that line be (depending on your setup)?

while( $row = $stmt->fetchAll( PDO::FETCH_OBJ) ){

var_dump( $row ) ;

}
Cups