[php] Why I am getting Cannot pass parameter 2 by reference error when I am using bindParam with a constant value?

I'm using this code and I'm beyond frustration:

try {
    $dbh = new PDO('mysql:dbname=' . DB . ';host=' . HOST, USER, PASS);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
}
catch(PDOException $e)
{
    ...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem

PDO::PARAM_NULL, null, '', all of them fail and throw this error:

Fatal error: Cannot pass parameter 2 by reference in /opt/...

This question is related to php mysql pdo null sql-insert

The answer is


If you want to insert NULL only when the value is empty or '', but insert the value when it is available.

A) Receives the form data using POST method, and calls function insert with those values.

insert( $_POST['productId'], // Will be set to NULL if empty    
        $_POST['productName'] ); // Will be to NULL if empty                                

B) Evaluates if a field was not filled up by the user, and inserts NULL if that's the case.

public function insert( $productId, $productName )
{ 
    $sql = "INSERT INTO products (  productId, productName ) 
                VALUES ( :productId, :productName )";

    //IMPORTANT: Repace $db with your PDO instance
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC.
    $query->bindValue(':productId',  !empty($productId)   ? $productId   : NULL, PDO::PARAM_INT); 

    //Works with strings.
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);   

    $query->execute();      
}

For instance, if the user doesn't input anything on the productName field of the form, then $productName will be SET but EMPTY. So, you need check if it is empty(), and if it is, then insert NULL.

Tested on PHP 5.5.17

Good luck,


I had the same problem and I found this solution working with bindParam :

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);

For those who still have problems (Cannot pass parameter 2 by reference), define a variable with null value, not just pass null to PDO:

bindValue(':param', $n = null, PDO::PARAM_INT);

Hope this helps.


In my case I am using:

  • SQLite,

  • prepared statements with placeholders to handle unknown number of fields,

  • AJAX request sent by user where everything is a string and there is no such thing like NULL value and

  • I desperately need to insert NULLs as that does not violates foreign key constrains (acceptable value).

Suppose, now user sends with post: $_POST[field1] with value value1 which can be the empty string "" or "null" or "NULL".

First I make the statement:

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

where {$sColumns} is sth like field1, field2, ... and {$sValues} are my placeholders ?, ?, ....

Then, I collect my $_POST data related with the column names in an array $values and replace with NULLs:

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

Now, I can execute:

$stmt->execute($values);

and among other bypass foreign key constrains.

If on the other hand, an empty string does makes more sense then you have to check if that field is part of a foreign key or not (more complicated).


Based on the other answers but with a little more clarity on how to actually use this solution.

If for example you have an empty string for a time value but you want to save it as a null:

  if($endtime == ""){
    $db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
  }else{
    $db->bind("endtime",$endtime);
  }

Notice that for time values you would use PARAM_STR, as times are stored as strings.


Try This.

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null

When using INTEGER columns (that can be NULL) in MySQL, PDO has some (to me) unexpected behaviour.

If you use $stmt->execute(Array), you have to specify the literal NULL and cannot give NULL by variable reference. So this won't work:

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

But this will work:

// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise

Tried this on MySQL 5.5.15 with PHP 5.4.1


When using bindParam() you must pass in a variable, not a constant. So before that line you need to create a variable and set it to null

$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);

You would get the same error message if you tried:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to mysql

Implement specialization in ER diagram How to post query parameters with Axios? PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver' phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' is not supported How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Connection Java-MySql : Public Key Retrieval is not allowed How to grant all privileges to root user in MySQL 8.0 MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

Examples related to pdo

Pass PDO prepared statement to variables PDO::__construct(): Server sent charset (255) unknown to the client. Please, report to the developers Laravel Migration Error: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes PHP 7 RC3: How to install missing MySQL PDO PHP Connection failed: SQLSTATE[HY000] [2002] Connection refused ERROR: SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it php artisan migrate throwing [PDO Exception] Could not find driver - Using Laravel How to check if a row exists in MySQL? (i.e. check if an email exists in MySQL) PDOException SQLSTATE[HY000] [2002] No such file or directory How do I configure php to enable pdo and include mysqli on CentOS?

Examples related to null

getElementById in React Filter values only if not null using lambda in Java8 Why use Optional.of over Optional.ofNullable? How to resolve TypeError: Cannot convert undefined or null to object Check if returned value is not null and if so assign it, in one line, with one method call How do I assign a null value to a variable in PowerShell? Using COALESCE to handle NULL values in PostgreSQL How to check a Long for null in java Check if AJAX response data is empty/blank/null/undefined/0 Best way to check for "empty or null value"

Examples related to sql-insert

In Oracle SQL: How do you insert the current date + time into a table? SQL Error: ORA-01861: literal does not match format string 01861 "Insert if not exists" statement in SQLite Column count doesn't match value count at row 1 Inserting data to table (mysqli insert) SQL Insert into table only if record doesn't exist C# with MySQL INSERT parameters How to speed up insertion performance in PostgreSQL "column not allowed here" error in INSERT statement Inserting multiple rows in mysql