I am getting the error:
Cannot pass parameter 2 by reference in.....
in this line...
$stmt1->bindParam(':value', $_SESSION['quantity'.$i] * $_SESSION['price'.$i], PDO::PARAM_STR);
What is wrong with code above ??
I'd say it's the typical confusion between PDO:bindParam() and what you probably intended to use: PDO:bindValue().
PDOStatement::bindParam
Binds a PHP variable to a corresponding named or question mark
placeholder in the SQL statement that was used to prepare the
statement. Unlike PDOStatement::bindValue(), the variable is bound
as a reference and will only be evaluated at the time that
PDOStatement::execute() is called.
PDOStatement::bindValue
Binds a value to a corresponding named or question mark placeholder in
the SQL statement that was used to prepare the statement.
It expects the second paramter to be a variable which can be passed by reference. Assuming $stmt1is a PDO statement then, as the docs for bindparam say
Unlike PDOStatement::bindValue(), the variable is bound as a reference
and will only be evaluated at the time that PDOStatement::execute() is
called.
Your second param is an expression ($_SESSION['quantity'.$i] * $_SESSION['price'.$i]) not a variable. Since you appear to want to evaluate the exptression now, I guess you should used bindValue() instead.
Related
I often see code using bindParam or bindValue with PDO. Is simply passing arguments to execute frowned upon for any reason?
I understand that bindParam actually binds to the variables and that you can set the type of parameter being bound with both bind methods, but what if you are only inserting strings?
$query = "SELECT col1 FROM t1 WHERE col2 = :col2 AND col3 = :col3 AND col4 = :col4";
$pdo->bindValue(':col2', 'col2');
$pdo->bindValue(':col3', 'col3');
$pdo->bindValue(':col4', 'col4');
I often see the above, but personally I prefer:
$pdo->execute(array(':col2' => 'col2', ':col3' => 'col3', ':col4' => 'col4'));
It is not as verbose and visually it makes more sense to me to have the inputs "going in" to the query together. However, I hardly ever see it used.
Is there a reason to prefer the bind methods over passing parameters to execute when you don't have to take advantage of the special behaviors of the former?
You might find bindParam used when you just want to bind a variable reference to a parameter in the query, but perhaps still need to do some manipulations on it and only want the value of the variable calculated at time of query execution. It also allows you to do more complex things like bind a parameter to a stored procedure call and have the returned value updated into the bound variable.
For more, see the bindParam documentation, bindValue documentation and execute documentation.
For example
$col1 = 'some_value';
$pdo->bindParam(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_other_value' for ':col1' parameter
bindValue and passing an array to execute behave in much the same way as the parameter value is fixed at that point and SQL executed accordingly.
Following the same example above, but using bindValue
$col1 = 'some_value';
$pdo->bindValue(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_value' for ':col1' parameter
When passing values directly in execute all values are treated as strings (even if integer value is provided). So if you need to enforce data types, you should always use bindValue or bindParam.
I think you might see bind* used more than execute(array) as many consider it to be better coding practice to explicitly define data types in parameter declarations.
By passing the parameters along with the $pdo->execute() method, all values in the array with be passed, as PDO::PARAM_STR to the statement with the $pdo->bindParam() function.
The main difference that I can see now, is that with the $pdo->bindParam() function, you can define the data type passed along, using the PDO::PARAM_* constants as described in the PHP.net manual
Simple,
the value of bindParam may change but the value of bindValue can not change.
Example:
$someVal=10;
$someVal2=20;
/* In bindParam, the value argument is not bound and
will be changed if we change its value before execute.
*/
$ref->bindParam(':someCol',$someVal);
$someVal=$someVal2;
$ref->execute();
//someCol=20
/* In bindValue, the value argument is bound and
never changed if we change its value before execute.
*/
$ref->bindValue(':someCol',$someVal);
// here assignment is referral (&$someVal)
$someVal=$someVal2;
$ref->execute();
//someCol=10
We have something like the following PDO Statement which we use to communicate with a PostgreSQL 8.4 DB.
$st = $db -> prepare("INSERT INTO Saba.Betriebskosten (personalkosten)
VALUES(:kd_personalkosten)");
$st -> bindParam(':kd_personalkosten', $val['kd_personalkosten']);
$val['kd_personalkosten'] is either empty/null or contains a double value. In the case it is empty/null, we just want to insert an empty value, but we receive the following error:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type double precision: '';
Which means that empty/null is converted to an empty STRING which is not compatible with the double precision field. How to circumvent this error?
it seems to me that value is "" (empty string) which bindParam converts to "" in SQL query, and since personalkosten is of type Double it raises the error.
This should fix this issue with empty text to double conversion:
$st -> bindParam(':kd_personalkosten', (float) $val['kd_personalkosten']);
If you would really want to insert NULL value when variable is empty then you should do this:
$value = $val['kd_personalkosten'];
if ($value === '' or $value === NULL) {
$st->bindValue(':kd_personalkosten', NULL, PDO::PARAM_NULL); // note the bindValue() instead of bindParam()
} else {
$st->bindParam(':kd_personalkosten', $value);
}
About bindValue vs bindParam from php manual:
bindParam()
Binds a PHP variable to a corresponding named or question mark
placeholder in the SQL statement that was used to prepare the
statement. Unlike PDOStatement::bindValue(), the variable is bound as
a reference and will only be evaluated at the time that
PDOStatement::execute() is called.
Most parameters are input parameters, that is, parameters that are
used in a read-only fashion to build up the query. Some drivers
support the invocation of stored procedures that return data as output
parameters, and some also as input/output parameters that both send in
data and are updated to receive it.
Basically bindValue allows you to bind a direct value or constant, whilst bindParam requires a variable or reference to be passed in.
I often see code using bindParam or bindValue with PDO. Is simply passing arguments to execute frowned upon for any reason?
I understand that bindParam actually binds to the variables and that you can set the type of parameter being bound with both bind methods, but what if you are only inserting strings?
$query = "SELECT col1 FROM t1 WHERE col2 = :col2 AND col3 = :col3 AND col4 = :col4";
$pdo->bindValue(':col2', 'col2');
$pdo->bindValue(':col3', 'col3');
$pdo->bindValue(':col4', 'col4');
I often see the above, but personally I prefer:
$pdo->execute(array(':col2' => 'col2', ':col3' => 'col3', ':col4' => 'col4'));
It is not as verbose and visually it makes more sense to me to have the inputs "going in" to the query together. However, I hardly ever see it used.
Is there a reason to prefer the bind methods over passing parameters to execute when you don't have to take advantage of the special behaviors of the former?
You might find bindParam used when you just want to bind a variable reference to a parameter in the query, but perhaps still need to do some manipulations on it and only want the value of the variable calculated at time of query execution. It also allows you to do more complex things like bind a parameter to a stored procedure call and have the returned value updated into the bound variable.
For more, see the bindParam documentation, bindValue documentation and execute documentation.
For example
$col1 = 'some_value';
$pdo->bindParam(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_other_value' for ':col1' parameter
bindValue and passing an array to execute behave in much the same way as the parameter value is fixed at that point and SQL executed accordingly.
Following the same example above, but using bindValue
$col1 = 'some_value';
$pdo->bindValue(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_value' for ':col1' parameter
When passing values directly in execute all values are treated as strings (even if integer value is provided). So if you need to enforce data types, you should always use bindValue or bindParam.
I think you might see bind* used more than execute(array) as many consider it to be better coding practice to explicitly define data types in parameter declarations.
By passing the parameters along with the $pdo->execute() method, all values in the array with be passed, as PDO::PARAM_STR to the statement with the $pdo->bindParam() function.
The main difference that I can see now, is that with the $pdo->bindParam() function, you can define the data type passed along, using the PDO::PARAM_* constants as described in the PHP.net manual
Simple,
the value of bindParam may change but the value of bindValue can not change.
Example:
$someVal=10;
$someVal2=20;
/* In bindParam, the value argument is not bound and
will be changed if we change its value before execute.
*/
$ref->bindParam(':someCol',$someVal);
$someVal=$someVal2;
$ref->execute();
//someCol=20
/* In bindValue, the value argument is bound and
never changed if we change its value before execute.
*/
$ref->bindValue(':someCol',$someVal);
// here assignment is referral (&$someVal)
$someVal=$someVal2;
$ref->execute();
//someCol=10
If i do this:
$qry->execute(array($usuario,$pass));
instead of this:
$qry->bindParam(1, $usuario);
$qry->bindParam(2, $pass);
$qry->execute();
does this give a security problem?
Nope, they are semantically identical
And it's specified in the documentation
Execute the prepared statement. If the prepared statement included parameter markers, you must either:
call PDOStatement::bindParam() to bind PHP variables to the parameter markers: bound variables pass their value as input and receive the output value, if any, of their associated parameter markers
or pass an array of input-only parameter values
No, it will not. It will work fine.
How can I pass a constant to the bind_param in mysqli prepared statements. The following works fine by passing variable:
$stmt->bind_param("i", $id);
But if i try to pass constant, it does not work.
For example:
$stmt->bind_param("i", ID);
Gives following error:
Fatal error: Cannot pass parameter 2 by reference in...
Thanks
In MySQLi, the arguments following the type strings are passed by reference, not by value. The only thing you can pass by reference is a variable. The reason for using variables is that you can assign the variables, execute the statement, assign the variables again, execute the statement again, etc. So try this:
$id = ID;
$stmt->bind_param("i", $id);
Or try using PDO's MySQL driver instead of MySQLi. PDO allows you to choose to bind a value instead of a variable to a query parameter. This is useful if you plan to execute a prepared statement only once.