$nam=$_POST['name'];
$fname=$_POST['family'];
$dat=$_POST['date'];
$bal=$_POST['balance'];
$curr=$_POST['currency'];
$con=mysql_connect('localhost', 'xxxx', 'xxxx', 'xxxx');
$db=mysql_select_db('users',$con);
$ins=mysql_query("INSERT INTO users (Name, FamilyName, Date, Balance, Currency) VALUES ('$nam', '$fname', '$dat', '$bal', '$curr'))",$con);
if (!mysql_query($ins,$con))
{
die('Error: ' . mysql_error($con));
}
So guys, I got this code and I am trying to do something like a registration form. I have tripple checked the names of the variables and the query itself is working when executed in SQL database. The thing is when I include it in my php script it returns that the Query was empty. I've looked around but all errors on the Web are around not assigning to a variable or having several insert statements and so on. So my question is why am i getting this when I am actually inputting data from a web form? Error: Query was empty
P.S.
Ok so what I mde of this: I removed the check that you said was for a second time that is the if (!mysql_query($ins,$con)) { die('Error: ' . mysql_error($con)); } part now i get execution but it does not really add the entry to the database and i cannot call it. That is the new name.
You're basically trying to use mysql_query() twice:
$ins=mysql_query("INSERT INTO users (Name, FamilyName, Date, Balance,
Currency) VALUES ('$nam', '$fname', '$dat', '$bal', '$curr'))",$con);
if (!mysql_query($ins,$con))
{
$ins will contain a valid MySQL resource if the query was executed correctly, but you're attempting to use it again in the if condition.
Just remove the mysql_query() part from the condition, like so:
if(!$ins) {
# code ...
}
That should fix this particular issue. But note that your code is vulernable to SQL injection. Also, mysql_* functions are deprecated and are soon to be removed. I recommend you switch to MySQLi or PDO and start using parameterized queries to be safe.
this is incorrect
if (!mysql_query($ins,$con))
why are you performing a query of a query ??
just use if (!$ins||!$con)) if you are trying to check if the query and connection has been successful
Related
The code below does exactly what it's expected to do. It adds a client into the database successfully. But I never told the query to execute or add a new client all I did was store the query in a variable and checked to see if it was valid in the if statement. I need some help understanding how the query executed.
$query = "INSERT INTO clients(id, name, email, phone, address, company, notes, date_added) VALUES(NULL, '$clientName', '$clientEmail', '$clientPhone', '$clientAddress', '$clientCompany', '$clientNotes', CURRENT_TIMESTAMP)";
$result = mysqli_query($connection, $query);
// if query was successful
if( $result ){
header("LOCATION: clients.php?update=success");
} else{
// something went wrong
echo "Error: $query <br>" . mysqli_error($connection);
}
The way you should be doing this is a little more self-explanatory:
// Prepare this query with placeholders for where the user data will go.
// This creates a prepared statement handle ($stmt)
$stmt = $connection->prepare("INSERT INTO clients(name, email, phone, address, company, notes, date_added)
VALUES(?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)");
// Bind the user data to the statement so it will be escaped properly
// and inserted correctly.
$stmt->bind_param(
"ssssss",
$clientName,
$clientEmail,
$clientPhone,
$clientAddress,
$clientCompany,
$clientNotes
);
// Execute the statement now that everthing is in place. This actually
// sends the query to the MySQL server to be executed and waits
// for the result. The result of this function call indicates success
// or failure.
if ($stmt->execute()) {
// Query was successful then `execute()` returns a logically true value
// and this block of code will run.
header("Location: clients.php?update=success");
} else {
// If that previous condition didn't trigger, then we end up here and
// this code will run instead.
echo "Error: $query <br>" . $connection->error;
}
If you have an AUTO_INCREMENT column don't specify it in your list of VALUES, you can omit it and it will be populated automatically. Any column with a NULL default can also be omitted. There's no point in force-inserting NULL if that's how it will end up anyway.
You also need to pay careful attention to how you insert your data. You cannot use string interpolation to do this, it's extremely dangerous. The bind_param method takes care of adding the data in a safe manner if you've created a prepared statement that has placeholder values (?). This all but guarantees your code will be safe, secure and free from escaping errors that can take a lot of time to identify and repair.
I've also switched this to use the object-oriented style of mysqli. Not only is this significantly less verbose, it also becomes more clear as to what the operation is being performed on. $stmt->function() is obviously something making use of or manipulating the $stmt object. If it's just one argument of many that can be harder to identify.
Specifying arguments directly to functions instead of leaning on these intermediate variables is also a good habit to get into. Things like $sql tend to clutter up your code and confuse the intent of that string, plus if you have several of them you're juggling, like $sql3 and $sql8 there's an opportunity to make a tiny typo that causes real problems.
The PHP code I have inserts the HTML form data from the previous page into the database and in the same SQL statement return the PostID back from the inserted data. The PostID column is AUTO_INCREMENTING. I have been researching this problem for a week or two now and have found no significant solutions.
<?php
include("dbconnect.php");
mysql_select_db("astral_database", $con);
session_start();
$username = $_SESSION['username'];
$forumtext = $_POST["forumtext"];
$forumsubject = $_POST["forumsubject"];
$postquery = 'INSERT INTO Forums (Creator, Subject, Content) VALUES ("$username", "$forumsubject", "$forumtext"); SELECT LAST_INSERT_ID()';
$result = mysql_query($postquery, $con);
if (!$con) {
echo "<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (331: dbconnect experienced fatal errors while attempting to connect)";
die();
}
if ($username == null) {
echo "<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (332: Username was not specified while attempting to send request)";
die();
}
if ($result != null) {
echo "last id: " . $result;
$fhandle = fopen("recentposts.txt", "r+");
$contents = file_get_contents("recentposts.txt");
fwrite($fhandle, json_encode(array("postid" => $result, "creator" => $username, "subject" => $forumsubject, "activity" => time())) . "\n" . $contents);
fclose($fhandle);
mysql_close($con);
header("location: http://astraldevgroup.com/forums");
die();
} else {
die("<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (330: Unhandled exception occured while posting forum to website.)<br>");
echo mysql_error();
}
mysql_close($con);
?>
First off, the mysql_query doesn't return anything from the SELECT statement. I haven't found anything that will properly run both the SELECT statement and the INSERT statement in the same query. If I try running them in two different statements, it still doesn't return anything. I tried running the following statement in the SQL console and it ran perfectly fine without errors.
INSERT INTO Forums (Creator, Subject, Content) VALUES ("Admin", "Test forum 15", "This is a forum that should give me the post id."); SELECT LAST_INSERT_ID();
The mysql_query function does not run multiple statements
Reference: http://php.net/manual/en/function.mysql-query.php
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server ...
That's one reason your call to mysql_query isn't returning a resultset.
The most obvious workaround is to not try to run the SELECT in the same query. You could use a call to the mysql_insert_id instead.
Reference: PHP: mysql_insert_id http://php.net/manual/en/function.mysql-insert-id.php
Answers to some of questions you didn't ask:
Yes, your example code is vulnerable to SQL Injection.
Yes, the mysql_ interface has been deprecated for a long time.
Yes, you should being using either PDO or mysqli interfaces instead of the deprecated mysql_ functions.
FOLLOWUP
Re-visiting my answer, looking again at the question, and the example code.
I previously indicated that the code was vulnerable to SQL Injection, because potentially unsafe values are included in the SQL text. And that's what it looked like on a quick review.
But looking at it again, that isn't strictly true, because variable substitution isn't really happening, because the string literal is enclosed in single quotes. Consider what the output from:
$foo = "bar";
echo '$foo';
echo '"$foo"';
Then consider what is assigned to $postquery by this line of code:
$postquery = 'INSERT ... VALUES ("$username", "$forumsubject", "$forumtext")';
Fixing that so that $username is considered to be a reference to a variable, rather than literal characters (to get the value assigned to $username variable incorporated into the SQL text) that would introduce the SQL Injection vulnerability.
Prepared statements with bind placeholders are really not that hard.
$result will never be null. It's either a result handle, or a boolean false. Since you're testing for the wrong value, you'll never see the false that mysql_query() returned to tell you that the query failed.
As others have pointed out, you can NOT issue multiple queries in a single query() call - it's a cheap basic defense against one form of SQL injection attacks in the PHP mysql driver. However, the rest of your code IS vulnerable other forms of injection attacks, so... better start reading: http://bobby-tables.com
Plus, on the logic side, why are you testing for a null username AFTER you try to insert that very same username into the DB? You should be testing/validating those values BEFORE you run the query.
First time posting to StackOverflow, but I've been a long time reader of the comments here.
I ran across a programming bug that I could not figure out after several hours, and couldn't find anything in the questions and responses that seemed to apply, so here goes my first post!
I'm using PHP and a MySQLi prepared statement to insert data that originates from a file into a database and stores each record from the file into an array ($dbData[]) that is passed to a function that performs the database storage. I have checked the array values for all four indices for each record and data exists in all record fields, although there is a lot of slashes (forward and backwards), apostrophes, quotes (single and double) and html tags in some of the string content.
The $dbData array correlates to the columns in the table for the insert.
The table is called "content" and it has a constraint on the second column that it cannot be null. It is named 'CText'.
The code that operates on the data array is in a function that is called within a loop for all of the file data. I am providing the contents of the function below without the function interface. For simplification purposes I have included code that connects to the database, but the code that actually creates the database connection resides outside the function.
$mysqli = new mysqli("example.com", "user", "password", "database");
...
$queryText = "insert into content values (?, ?, ?, ?)";
$query = mysqli->prepare($queryText);
$query->bind_param('dsds',$dbData[0],$dbData[1],$dbData[2],$dbData[3]);
if (!$query->execute()) {
echo '<br>Execute failed: (' . $query->errno . ') . $query->error;
echo '<br>dbData[1]: ' . $dbData[1];
}
The insert works for most of the $dbData record data, but I get this error on a few of the records:
Execute failed: (1048) Column 'CText' cannot be null
CText: {data printed here that is truncated after what appears to be a line return in the string content}
My question is whether the bind may have issues with certain characters, like a line feed/carriage return or some other combination. I have not set a character encoding in the code so the default encoding is in use.
whether the bind may have issues with certain characters, like a line feed/carriage return or some other combination.
No. There are no issues with bind. The only reason for such error message is when data IS null.
Here goes simple checklist for solving all the problems of the kind.
Trust your eyes. You are not a sole user of mysqli prepared statements. There are millions of them, and noone experienced such a problem yet. Means if database is reporting that value cannot be null, then value IS null.
Anyway, if you still thinks that there is a bug - create an isolated, reprobuceable code example. Means not just create unworkable sketch to show to the readers, but a complete working example that anyone can reproduce. Such as
$mysqli = new mysqli("example.com", "user", "password", "database");
$mysqli->query("CREATE TABLE content ...");
$queryText = "insert into content values (?, ?, ?, ?)";
$query = $mysqli->prepare($queryText);
$dbData[0] = 0;
$dbData[1] = 'some text that yo think is causing the error';
$dbData[2] = 0;
$dbData[3] = 'some another text';
$query->bind_param('dsds',$dbData[0],$dbData[1],$dbData[2],$dbData[3]);
if (!$query->execute()) {
echo '<br>Execute failed: (' . $query->errno . ') . $query->error;
echo '<br>dbData[1]: ' . $dbData[1];
}
without loops. without any code that is not shown - but a complete, working example that produces the noted error.
After failing with such an example, start debugging your code, to find a logical error either with program flow or the way you debug it.
You have to realize that this kind of questions ("I have a bug in PHP out of the clear sky") cannot have another receive without a reproduceable example.
PHP code from registration procedure:
$query="INSERT INTO `users`(`email`, `password`, `role`, `time_registration`)
VALUES ('".mysqli_real_escape_string($con, trim($_SESSION['reg']['email']))."',
'".hash('SHA512',trim($_POST['password']))."',
'".mysqli_real_escape_string($con, trim($_SESSION['rola']))."',
NOW())";
if(!mysqli_query($con, $query)){
error(".....");
}else{
Here is all good. First query is executed and data is stored to table "users". But here comes problem. Next php code generate new mysql query, which is never executed. But when I copy it to PHPmyAdmin, there it works...
$last_id=$con->insert_id;
$query='';
foreach($_SESSION['reg'] as $key=>$value){
if($value!=''){
$query.=" INSERT INTO user_detail (id_user,id_item,value) VALUES ('".$last_id."', (SELECT id_item FROM profil_items WHERE name='".$key."'), '".mysqli_real_escape_string($con, $value)."');";
}
}
if(!mysqli_query($con, $query)){
echo $query;
}else{
header('Location: ...somewhere....');
}
}
Mysqli error message: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO user_detail (id_user,id_item,value) VALUES ('14', (SELECT id_po' at line 1".
I dont understand. If there is an error in syntax, how can by executed without errors in PHPmyAdmin?
There is never any reason to use mysqli_multi_query(). Starting a habit of using multi-query opens yourself up to new types of SQL injection vulnerabilities.
You should either execute each INSERT individually, with mysqli_query() inside the foreach loop.
Or else append multiple rows into one multi-row INSERT statement and execute it after the loop.
In this case, no (though you should use bound parameters instead of mysqli_real_escape_string()), but I think once you start using mysqli_multi_query() you may use it elsewhere in an unsafe manner. Better to never use it.
You can execute a single INSERT by using multi-row syntax. But I wouldn't worry about the overhead of executing multiple statements, until you are doing it in such high volume that you can measure a significant performance problem. Don't worry about micro-optimizations.
I'm trying to loop data from a api and then post these values to a MySQL db.
something like this:
$values = json_decode(file_get_contents("my-json-file"));
$SQL = new mysqli(SQL_HOST, SQL_USER, SQL_PASS, DB_NAME);
$SQL->autocommit(FALSE);
foreach($values As $item)
{
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";)";
$SQL->query($query);
if(!$SQL->commit())
{
echo "ERROR ON INSERT: [" . $query . "]<hr/>";
}
}
$SQL->close();
Since the loop is too fast, the SQL can't catch up. (Yea!)
I would then need something like this:
foreach($values As $item)
{
/**** STOP/PAUSE LOOP ****/
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";");
$SQL->query($query);
if($SQL->commit())
{
/**** START THE LOOP AGAIN ****/
}
else
{
echo "ERROR ON INSERT: [" . $query . "]<hr/>";
}
}
Or how should I do this the right way?
EDIT: It inserts random posts every time.
EDIT 2: This is just example code. It does escape and all that, and yes the semi colon is wrong here but since so many commented on it i will not change it. This was not the problem in the real case.
I tried to run it on another server and there it worked. The problem was fixed by restarting MAMP.
Firstly, your idea that the loop runs too fast for MySQL to keep up is completely totally wrong. The $SQL->query() call will wait for the MySQL to return a response before proceeding, so the loop won't run any faster than MySQL is responding.
Now onto the actual problem.... your query:
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";)";
There's a semi-colon in there at the end, after value2 which is invalid. I guess you intended to type a quote mark there? The semi-colon will be causing all your queries to fail and throw errors.
This may be the cause of your problem but you haven't got any error checking in there, so you won't know. Add some error checking to your code after calling the query; even if the query is right, it's still possible to get errors, and your code should check for them. See the examples on this manual page: http://www.php.net/manual/en/mysqli-stmt.error.php
Finally, since you're using the mysqli API, it's worth mentioning that your code would be a lot better and probably more secure if you used prepared statements. See the examples in PHP manual here: http://www.php.net/manual/en/mysqli-stmt.bind-param.php
[EDIT]
Another possible reason your query is failing is that you're not escaping the input values. If any of the input values contains a quote character (or any other character that is illegal in SQL) then the query will fail. In addition, this problem makes your code vulnerable to a SQL injection hacking attack.
You need to escape your input using $SQL->real_escape_string() OR by changing your query to use prepared statements (as recommended above).
Your query is inside the loop, which means that the loop will wait until your query finished executing before it continue, php code is processed in order...
Has #phpalix said, PHP goes in order, and waits for the previous action to finish.
I think you SQL is wrong. Try replacing your INSERT with this:
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2."');";
And don't forget to run at least mysql_real_escape_string for each variable, for security measures.
As many of the answers and comments say, it does not continue until the SQL is done. The problem was in my local apache/mysql server. It was fixed by restarting it. Yes, stupid post.