PHP MySQLi prepared statement - should I include all the fields? - php

Here is an example:
if($stmt = $mysqli -> prepare("
INSERT INTO
jos_virtuemart_product_categories
(
virtuemart_product_id,
virtuemart_category_id,
ordering
)
VALUES
(
?,
?,
0
)"))
{
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ii", $pid, $productcategory);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
/* Close statement */
$stmt -> close();
}
Now, if you look at one of my inserts, I am directly inserting 0, and not passing it through a prepare statement.
Is this workable?The reason I am asking is because I have statements with a TON of fields, where many fields are exactly the same for all rows, but only differs in perhaps two or three, which I get from a loop through a result set.
Thanks

If those are the same for all inserts, you can leave them hardcoded in the query - no need to make your code filled with useless things. The cleaner, the better - right?
Furthermore, you can alter the fields so that those values are the DEFAULT values - so that would eliminate the need to put them in the query.

Related

bind_result error when using prepared statement [duplicate]

I'm getting:
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't
match number of fields in prepared statement in
E:\XAMPP\htdocs\account\lib\register.php on line 73
When I use this code:
if($stmt = $conn -> prepare("INSERT INTO login(user, pass) VALUES(?, ?)")) {
/* Bind parameters s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pw);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($user, $pw);
/* Close statement */
$stmt -> close();
$userId = $conn->insert_id;
}
I can't understand, why this happens every time, what is wrong in my code snippet?
You are attempting to bind_result on a statement that is not returning any results.
Remove this line.
$stmt -> bind_result($user, $pw);

What are the differences array usage and bindParam usage during mysql data inserting?

I am preparing mysql configuration settings using class. I am confused about it. I always use bindParam. It also possible to insert using array. I mean, what are the differences between array and bindparam.
eg array
$query = $db->prepare("INSERT INTO users SET
username = :uname,
password = :upass,
email = :umail");
$insert = $query->execute(array(
"upass" => "123456",
"umail" => "user#user.com",
"uname" => "username",
));
if ( $insert ){
$last_id = $db->lastInsertId();
}
eg
$stmt = $this -> db_conn -> prepare("INSERT into users(username, password) VALUES(:uname, :upass)");
$stmt -> bindParam(':uname', $username);
$stmt -> bindParam(':upass', $password);
$stmt -> execute();
Desconsidering the fact that with execute you can't choose the data type (it's always PDO::PARAM_STR) There's only a main difference between both (which is from core). PDOStatement::bindParam is by reference while PDOStatement::execute isn't. PDOStatement::execute do internnaly the same thing as PDOStatement::bindValue, but twice.
Internally (in C), bindValue calls the same method which execute calls. The method name which is called is really_register_bound_param.
On the other hand, bindParam calls other method called register_bound_param.
It means that bindValue calls the same method called by execute more than one time while bindParam calls a method to bind as a reference and only "really register" the param when execute is called.
Thinking about bind by reference, it's only possible using bindParam:
//fictional code
$stmt= $pdo->prepare("INSERT INTO table (column) VALUES (:value)");
$stmt->bindParam(":value", $randomValue);
for($i = 0 ; $i < 1000; $i))
{ $randomValue = rand(1000,1000000);
$stmt->execute();
}
Is it worthy? Perhaps while a while with a complex insert with multiples parameters could reduce the overhead with rebinding a new parameter or a big amount of them.

INSERT - Number of bind variables doesn't match number of fields in prepared statement

I'm getting:
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't
match number of fields in prepared statement in
E:\XAMPP\htdocs\account\lib\register.php on line 73
When I use this code:
if($stmt = $conn -> prepare("INSERT INTO login(user, pass) VALUES(?, ?)")) {
/* Bind parameters s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pw);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($user, $pw);
/* Close statement */
$stmt -> close();
$userId = $conn->insert_id;
}
I can't understand, why this happens every time, what is wrong in my code snippet?
You are attempting to bind_result on a statement that is not returning any results.
Remove this line.
$stmt -> bind_result($user, $pw);

Which is correct way to get last inserted id in mysqli prepared statements procedural style?

i am using mysqli prepared statement to insert record in the table like this
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
/* check connection */
if (!$link) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
/* execute prepared statement */
mysqli_stmt_execute($stmt);
if(mysqli_stmt_affected_rows($stmt) > 0){
//if insert is successful then get the insrted id.
}
/* close statement and connection */
mysqli_stmt_close($stmt);
/* close connection */
mysqli_close($link);
and would like to get the last inserted id , as the table has record_num field which is auto increment .
so my question is should i place connection name or the statement name inside the function.
i.e
1)
echo mysqli_insert_id($link);
Source: http://php.net/manual/en/mysqli.insert-id.php
2)
echo mysqli_stmt_insert_id($stmt);
Source: http://php.net/manual/en/mysqli-stmt.insert-id.php
which one is correct ?
which one will give me last insrted id by the $stmt ?
there are no other inserts are being done using the same stmt one the same page..*
Update:
according to the note from http://php.net/manual/en/mysqli-stmt.insert-id.php
I am doing only single insert so i guess i can use
mysqli_stmt_insert_id($stmt)
but while doing multiple inserts using prepared statements using
echo mysqli_insert_id($link);
is best practice.
You should use
mysqli_insert_id($link);
Because of this note on the PHP manual you referred us to
mysqli_stmt_insert_id
It should be noted that using mysqli_stmt->insert_id will not result in a unique ID being returned for each execution of a prepared insert statement. In practice, it appears that the first insertion ID is returned. If you are performing multiple inserts with the same prepared statement (one invocation of mysqli_stmt::prepare and multiple invocations of mysqli_stmt::execute() for a given statement), and need to keep the unique ID for each insert, use mysqli_connection->insert_id.
for procedural language you need to use below code,
mysqli_insert_id($link));
yes as you mention in 1 point.
Correct is 1) - link, as stated in documentation:
http://php.net/manual/en/mysqli.insert-id.php

How does SQL logic in this php 'know' what to select?

I apologise if the title is poor.
I have been researching Prepared Statements and found the following code here:
/* Create a new mysqli object with database connection parameters */
$mysqli = new mysqli('localhost', 'username', 'password', 'db');
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT priv FROM testUsers WHERE username=?
AND password=?")) {
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pass);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $user . "'s level of priviledges is " . $result;
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
The part that I don't understand, is how in the SQL Query "SELECT priv FROM testUsers WHERE username=?
AND password=?"), the system knows what the username and password is. I know that the ? marks are placeholders, and below is also confusing me a bit:
$stmt -> bind_param("ss", $user, $pass);
Because I do not see how the $user and $pass have been defined at any point, and thus how the SQL query will substitute the $user and $pass for an actual string. If that makes sense. Where have these values come from? Where are they in this example?
That's because they aren't. This is probably just an example how to use the script. You will have to define the $user and $pass variables by yourself, for example from an $_POST variable of some sort.
The bind_param function handles the arguments. You have to add the same amount of arguments to the query as you put question marks in it. Than the parser in the core of MySQLi can add the arguments safely to the query.
They are being matched by order. Same logic in string building ("{0} is greater than {1}", "5", "3") becomes 5 is greater than 3. So with parameters
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
they are all ordered and matches with columns.
If the original script writer had register_globals ON, e.g. in a previous version of PHP, then the user and pass were passed in from the form in the same way as $_POST['user'] and $_POST['pass']. I offer that you can replace them now and move on.

Categories