This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 3 years ago.
$Createdby=$_SESSION['adminlog'];
$total =$_POST['total'];
$due =$_POST['due'];
$date =$_POST['issedate'];
$invoiceno =$_POST['invno'];
$CmpnyName =$_POST['CmpnyName'];
$itemdetails =$_POST['item_details'];
$itemname =$_POST['itemname'];
$amtpaid =$_POST['paid'];
$query = "UPDATE billdata SET Total='$total' Due='$due' WHERE InvoiceNo=$invoiceno";
$result = mysql_query($query);
This is the code I am using to get HTML values to variable and update particular invoice number with new data.
First off, never use the deprecated mysql_* API.
Switch to either PDO or mysqli, both have prepared statements, which would make your code a tad bit more safe when it comes to SQL-Injections (which your code is very open for).
When a query fails, the mysql_error() global function will return the latest mysql error.
The easiest way to get information about a failing query is by adding or die(mysql_error()); after the query execution.
Example with your code:
$result = mysql_query($query) or die(mysql_error());
This will report your error and stop execute the script.
Your sql code is slightly wrong (as RST mentions), you are missing a comma between the values you are trying to set.
Using mysqli and prepared statements, your code could look something like:
// Using the mysqli object oriented style.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'username', 'password', 'database');
// Prepare the statement.
$statement = $mysqli->prepare('UPDATE billdata SET Total=?, Due=? WHERE InvoiceNo=?');
// The question marks is placeholders for the input that will be added in a while.
// Bind your parameters (ssi tells mysqli what type of params it is, s = string, i = int).
$statement->bind_param('ssi', $total, $due, $invoceno);
// Execute the statement.
$statement->execute();
// Cleanup.
$statement->close();
$mysqli->close();
$query = "UPDATE billdata SET Total='$total', Due='$due' WHERE InvoiceNo=$invoiceno";
There should be a comma between the sets of values.
It is not a good idea to use the value from $_POST() as they are, better perform some validation checks.
Related
I am trying out prepared statements, but the below code is not working. I am getting the error:
Fatal error: Call to a member function execute() on a non-object in
/var/www/prepared.php on line 12
<?php
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// insert one row
$stmt->execute(array('one',1));
// insert another row with different values
$stmt->execute(array('two',1));
?>
Also, do I need to use mysqli for prepared statements? Can anyone point me to a complete example on prepared statements from connection to insertion to selection with error handling?
From the mysqli::prepare docs:
The parameter markers must be bound to application variables using mysqli_stmt_bind_param() and/or mysqli_stmt_bind_result() before executing the statement or fetching rows.
bind_param docs.
i.e.:
$name = 'one';
$age = 1;
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// bind parameters. I'm guessing 'string' & 'integer', but read documentation.
$stmt->bind_param('si', $name, $age);
// *now* we can execute
$stmt->execute();
Also do I need to use mysqli for prepared statement. Can anyone point me to a complete example on prepared statement from connection to insertion to selection with error handling
You can also use PDO which I much prefer. In fact, it looks like you're confusing PDO and Mysqli in your code example.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (?,?)");
$stmt->execute(array($name1, $age1));
$stmt->execute(array($name2, $age2));
Unlike with mysqli you don't have to call a separate binding function, although that feature is available if you prefer/want/need to use it.
Another fun thing about PDO is named placeholders which can be much less confusing in complex queries:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (:name,:age)");
$stmt->execute(array(':name' => $name1, ':age' => $age1));
$stmt->execute(array(':name' => $name2, ':age' => $age2));
Connection
The importance of mysqli connection is often overlooked, being diminished to a single line. Whereas a correct connection code can solve a multitude of problems, from security to usability.
Given your code is the usual procedural PHP, here is a simple mysqli connection code to be included in your scripts:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
The full explanation can be found in my article How to connect properly using mysqli (as well as many useful hints), but just a small citation to highlight most important parts:
setting the proper character set for the connection will eliminate the whole class of errors, such as weird characters/question marks instead of your data, empty json_encode() output, problems with storing emojis, etc.
setting the proper error reporting mode will eliminate the cryptic error messages like mysqli_fetch_assoc() expects parameter... / Call to a member function bind_param()..., giving you the actual error message from MySQL instead.
security is not a laughing matter, there should be not a chance to leak your database details to the outside
Insertion
Insert query is relatively simple, and it is already covered in the other answer.
All you need is to replace all variables (along with surrounding quotes!) in the query with question marks, then prepare the query, then shove all variables with their types into bind_param() and finally execute the query.
Only a quick tip: MySQL will gladly accept all variables as strings, so don't go nuts finding the correct type for a certain variable, simply using "s" for any.
So basically inserting would be like this
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
The same principle should be used for all other query types, such as UPDATE or DELETE.
Selection
Running a select query is almost the same, but with one small trick. For some unknown reason you cannot use familiar fetch functions right off the prepared statement. So you need to get the mysqli_result first, and then you'll be able to use fetch_assoc(), fetch_obj() etc:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
Tip: there is absolutely no need for the familiar mysqli_num_rows() function. If you think of it, you can always use the data itself, to see whether your query returned any rows:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
the same goes for the multiple rows, thanks to
another tip: there is a handy function fetch_all() that can get you an array of all selected rows in one go. For example, if a query returns multiple rows, you can get them into array by changing the last line to
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
Error handling
Error handling is the most important yet somewhat surprising part. Despite what numerous articles and examples say, as a rule, you shouldn't write any error handling code at all. It sounds absolutely crazy but that's exactly how things must be done. Most of time all you need to do is just report the error. And mysqli/PHP already can do it for you, no help required. Therefore, you shouldn't write any code that verifies the query execution result - in case of error mysqli will report it automatically, thanks to the mysqli_report() function call mentioned in the #Connection part. Again, the full explanation of this principle can be found in another article, dedicated to general PHP error reporting.
On a rare occasion when you really need to handle the error, that is to perform some action in case of error instead of just reporting it, then wrap your query(es) in a try..catch.
I am trying out prepared statements, but the below code is not working. I am getting the error:
Fatal error: Call to a member function execute() on a non-object in
/var/www/prepared.php on line 12
<?php
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// insert one row
$stmt->execute(array('one',1));
// insert another row with different values
$stmt->execute(array('two',1));
?>
Also, do I need to use mysqli for prepared statements? Can anyone point me to a complete example on prepared statements from connection to insertion to selection with error handling?
From the mysqli::prepare docs:
The parameter markers must be bound to application variables using mysqli_stmt_bind_param() and/or mysqli_stmt_bind_result() before executing the statement or fetching rows.
bind_param docs.
i.e.:
$name = 'one';
$age = 1;
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// bind parameters. I'm guessing 'string' & 'integer', but read documentation.
$stmt->bind_param('si', $name, $age);
// *now* we can execute
$stmt->execute();
Also do I need to use mysqli for prepared statement. Can anyone point me to a complete example on prepared statement from connection to insertion to selection with error handling
You can also use PDO which I much prefer. In fact, it looks like you're confusing PDO and Mysqli in your code example.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (?,?)");
$stmt->execute(array($name1, $age1));
$stmt->execute(array($name2, $age2));
Unlike with mysqli you don't have to call a separate binding function, although that feature is available if you prefer/want/need to use it.
Another fun thing about PDO is named placeholders which can be much less confusing in complex queries:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (:name,:age)");
$stmt->execute(array(':name' => $name1, ':age' => $age1));
$stmt->execute(array(':name' => $name2, ':age' => $age2));
Connection
The importance of mysqli connection is often overlooked, being diminished to a single line. Whereas a correct connection code can solve a multitude of problems, from security to usability.
Given your code is the usual procedural PHP, here is a simple mysqli connection code to be included in your scripts:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
The full explanation can be found in my article How to connect properly using mysqli (as well as many useful hints), but just a small citation to highlight most important parts:
setting the proper character set for the connection will eliminate the whole class of errors, such as weird characters/question marks instead of your data, empty json_encode() output, problems with storing emojis, etc.
setting the proper error reporting mode will eliminate the cryptic error messages like mysqli_fetch_assoc() expects parameter... / Call to a member function bind_param()..., giving you the actual error message from MySQL instead.
security is not a laughing matter, there should be not a chance to leak your database details to the outside
Insertion
Insert query is relatively simple, and it is already covered in the other answer.
All you need is to replace all variables (along with surrounding quotes!) in the query with question marks, then prepare the query, then shove all variables with their types into bind_param() and finally execute the query.
Only a quick tip: MySQL will gladly accept all variables as strings, so don't go nuts finding the correct type for a certain variable, simply using "s" for any.
So basically inserting would be like this
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
The same principle should be used for all other query types, such as UPDATE or DELETE.
Selection
Running a select query is almost the same, but with one small trick. For some unknown reason you cannot use familiar fetch functions right off the prepared statement. So you need to get the mysqli_result first, and then you'll be able to use fetch_assoc(), fetch_obj() etc:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
Tip: there is absolutely no need for the familiar mysqli_num_rows() function. If you think of it, you can always use the data itself, to see whether your query returned any rows:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
the same goes for the multiple rows, thanks to
another tip: there is a handy function fetch_all() that can get you an array of all selected rows in one go. For example, if a query returns multiple rows, you can get them into array by changing the last line to
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
Error handling
Error handling is the most important yet somewhat surprising part. Despite what numerous articles and examples say, as a rule, you shouldn't write any error handling code at all. It sounds absolutely crazy but that's exactly how things must be done. Most of time all you need to do is just report the error. And mysqli/PHP already can do it for you, no help required. Therefore, you shouldn't write any code that verifies the query execution result - in case of error mysqli will report it automatically, thanks to the mysqli_report() function call mentioned in the #Connection part. Again, the full explanation of this principle can be found in another article, dedicated to general PHP error reporting.
On a rare occasion when you really need to handle the error, that is to perform some action in case of error instead of just reporting it, then wrap your query(es) in a try..catch.
I have a MySQL Database Table containing products and prices.
Though an html form I got the product name in a certain php file.
For the operation in this file I want to do I also need the corresponding price.
To me, the following looks clear enough to do it:
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
However, its echo returns:
Resource id #5
instead a value like like:
59.95
There seem to be other options like
mysqli_fetch_assoc
mysqli_fetch_array
But I can't get them to output anything meaningful and I don't know which one to use.
Thanks in advance.
You will need to fetch data from your database
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
$result = mysql_fetch_array($price);
Now you can print it with
echo $result['price'];
As side note I would advise you to switch to either PDO or mysqli since mysql_* api are deprecated and soon will be no longer mantained
If you read the manual at PHP.net (link), it will show you exactly what to do.
In short, you perform the query using mysql_query (as you did), which returns a Result-Resource. To actually get the results, you need to perform either mysql_fetch_array, mysql_fetch_assoc or mysql_fetch_object on the result resource. Like so:
$res = mysql_query("SELECT something FROM somewhere"); // perform the query on the server
$result = mysql_fetch_array($res); // retrieve the result from the server and put it into the variable $result
echo $result['something']; // will print out the result you retrieved
Please be aware though that you should not use the mysql extension anymore; it has been officially deprecated. Instead you should use either PDO or MySQLi.
So a better way to perform the same process, but using for example the MySQLi extension would be:
$db = new mysqli($host, $username, $password, $database_name); // connect to the DB
$query = $db->prepare("SELECT price FROM items WHERE itemId=?"); // prepate a query
$query->bind_param('i', $productId); // binding parameters via a safer way than via direct insertion into the query. 'i' tells mysql that it should expect an integer.
$query->execute(); // actually perform the query
$result = $query->get_result(); // retrieve the result so it can be used inside PHP
$r = $result->fetch_array(MYSQLI_ASSOC); // bind the data from the first result row to $r
echo $r['price']; // will return the price
The reason this is better is because it uses Prepared Statements. This is a safer way because it makes SQL injection attacks impossible. Imagine someone being a malicious user and providing $itemId = "0; DROP TABLE items;". Using your original approach, this would cause your entire table to be deleted! Using the prepared queries in MySQLi, it will return an error stating that $itemId is not an integer and as such will not destroy your script.
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 8 years ago.
So I am having this strange issue with PDO, in that queries with bound variables are not executing properly for some reason. Let me show some code:
$conn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pwd);
$sth=$conn->prepare("select count(*) from article");
$sth->execute();
var_dump($sth->fetchColumn());
This will print out the correct number of entries in the table "article".
However, if we change it slightly, by making the table a named parameter instead of a constant:
$conn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pwd);
$sth=$conn->prepare("select count(*) from :article");
$sth->execute(array(":article"=>"article"));
var_dump($sth->fetchColumn());
This will print a boolean false. Both statements should return the same result, but I have no idea why the second one is not working. I suspect I have a typo somewhere, but I checked several times, and I don't see any issue. Anyone have any idea?
Not possible. You're trying to use a placeholder for a tablename. This is not permitted. placeholders can only replace values.
SELECT count(*) FROM :table WHERE field=:article
^^^^^^--illegal ^^^^^^^^--legal
For this, you'll have to use old-fashion string building:
$table = "article";
$sth=$conn->prepare("select count(*) from $table");
which then re-opens the SQL injection attack vulnerability, because you're now directly inserting external data into an SQL string.
Generally I connect and retrieve data using the standard way (error checking removed for simplicity):
$db = mysql_select_db("dbname", mysql_connect("host","username","passord"));
$items = mysql_query("SELECT * FROM $db");
while($item = mysql_fetch_array($items)) {
my_function($item[rowname]);
}
Where my_function does some useful things witht that particular row.
What is the equivalent code using objects?
Since version 5.1, PHP is shipped with the PDO driver, which gives a class for prepared statements.
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password); //connect to the database
//each :keyword represents a parameter or value to be bound later
$query= $dbh->prepare('SELECT * FROM users WHERE id = :id AND password = :pass');
# Variables are set here.
$query->bindParam(':id', $id); // this is a pass by reference
$query->bindValue(':pass', $pass); // this is a pass by value
$query->execute(); // query is run
// to get all the data at once
$res = $query->fetchall();
print_r($res);
see PDO driver at php.net
Note that this way (with prepared statements) will automatically escape all that needs to be and is one of the safest ways to execute mysql queries, as long as you use binbParam or bindValue.
There is also the mysqli extension to do a similar task, but I personally find PDO to be cleaner.
What going this whole way around and using all these steps gives you is possibly a better solution than anything else when it comes to PHP.
You can then use $query->fetchobject to retrieve your data as an object.
You can use the mysql_fetch_object()
http://is2.php.net/manual/en/function.mysql-fetch-object.php