2
<?php
    $connection=new PDO("mysql:host=localhost;dbname=userdata", "secure_credentials", "battery_staple");
    $user=$_POST['username1'];
    $pass=$_POST['password1'];
    $snip=mb_substr($user, 0, 3);
    $pass=password_hash($pass, PASSWORD_BCRYPT);
    $user_query=$connection->prepare("INSERT INTO login (email, password, semod, snippet) VALUES (:email, :password, :semod, :snippet)");
    $user_query->bindParam(':email', $user);
    $user_query->bindParam(':password', $pass);
    $user_query->bindParam(':semod', "false");
    $user_query->bindParam(':snippet', $snip);
    $user_query->execute;

(Password changed)

I'm facing a small problem with the above PHP code, whenever it's executed I get this error:

Fatal error: Cannot pass parameter 2 by reference in [location] on line [##: I shortened the above code... it's the password field with issues]

Looking around, this seems to be an issue when passing an string/integer directly, without using a variable. However, password_hash() returns a string, so I am led to believe that it's not returning a string. What could be the problem of this issue?

Anonymous Penguin
  • 2,027
  • 4
  • 34
  • 49
  • 6
    Wrong field, the issue is the `:semod` placeholder. You rare trying to pass a string literal (*"false"*) which cannot be used in `bindParam`. Use `bindValue` instead – Phil Apr 15 '14 at 01:24
  • possible duplicate of [PDO: bindParam versus bindValue](http://stackoverflow.com/questions/1179874/pdo-bindparam-versus-bindvalue) – Phil Apr 15 '14 at 01:26
  • 2
    The error message has the line number in it. How did you end up thinking that the error was with `password_hash`, since I'll bet any amount that the line number points to the `:semod` line. – Barmar Apr 15 '14 at 01:28
  • FYI - MySQL has a [boolean data type](https://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html#idm47351114471024) which would be a much better fit than the string *"false"* which is truthy in nature – Phil Apr 15 '14 at 01:33
  • @Phil Oops, if nothing else it shows that the error messages are on the "array scheme" (starting with 0). – Anonymous Penguin Apr 15 '14 at 01:36
  • @AnnonomusPerson no, they aren't. File line numbers in error messages are not zero-based indexes – Phil Apr 15 '14 at 01:38
  • @Phil I meant the "parameter 2", not the file line. – Anonymous Penguin Apr 15 '14 at 01:39
  • @AnnonomusPerson It's referring to the second argument (ie *"parameter 2"*) that you've passed to `bindParam` – Phil Apr 15 '14 at 01:42

1 Answers1

5

Your error is on this line:

$user_query->bindParam(':semod', "false");

You need to use bindValue.

$user_query->bindValue(':semod', "false");

bindParam passes the second argument by reference, so it has to be a variable, not a literal.

Additionally, known values don't need to be bound. You could have just as easily added the literal 'false' string to your statement query, ie

"INSERT INTO login (email, password, semod, snippet) VALUES (:email, :password, 'false', :snippet)"
Phil
  • 157,677
  • 23
  • 242
  • 245
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Just as a btw, is there any point in using bindParam for an input only parameter in the first place? – Matti Virkkunen Apr 15 '14 at 01:29
  • @MattiVirkkunen Handy in a loop where the bound reference value may change. – Phil Apr 15 '14 at 01:30
  • If you mean is there any point in using it for a hard-coded parameter, not much. But it can make the query easier to read. – Barmar Apr 15 '14 at 01:31
  • @Barmar You should add that (hard-coded parameters) to your answer. It's definitely worth pointing out that known values don't need binding – Phil Apr 15 '14 at 01:35
  • @Barmar Hope you don't mind, I added it to your answer for you. Then I upvoted. It felt kinda weird :) – Phil Apr 15 '14 at 01:43
  • @Phil FYI, when I review suggested edits, I usually reject edits like yours. – Barmar Apr 15 '14 at 02:03