MySQL/PHP Inserting the same row twice - php

I can't figure out why this code is inserting the same row twice. I've literally stripped it back to the following code:
<?php
$query = "INSERT INTO `cs_social_alerts` (email) VALUES ('test#test.com')";
mysql_query($query);
?>
The MySQL table it's being inserted into has 10 columns in it, but even with all of them mentioned in the query, it still inserts 'test#test.com' on two rows, with separate primary keys.
I've created a new WordPress page to run this on as all other pages seem to be functioning fine without the duplication.
I've done some Googling which hasn't found much of any help - Is there any way I can check where the second query is coming from? I've starred at the above code for about an hour now and cannot see any issues with it.
So here's the result from the debug traceback, the code that's being run is literally the 2 lines above - I've blanked the domain for security. Can anyone see any interference?
#0 eval() called at [/var/sites/c/****.com/public_html/wp-content/plugins/wp-exec-php/wp-exec-php.php:652]
#1 WP_exec_PHP->exec(
$myQuery = "INSERT INTO `cs_social_alerts` (email) VALUES ('test#test.com')";
mysql_query($myQuery);
debug_print_backtrace()
?>
) called at [/var/sites/c/****.com/public_html/wp-content/plugins/wp-exec-php/wp-exec-php.php:692]
#2 WP_exec_PHP->_exec_post(
$myQuery = "INSERT INTO `cs_social_alerts` (email) VALUES ('test#test.com')";
mysql_query($myQuery);
debug_print_backtrace()
?>
)
#3 call_user_func_array(Array ([0] => WP_exec_PHP Object ([] => Array (),[] => /var/sites/c/*****.com/public_html/wp-content/plugins/wp-exec-php/wp-exec-php.php),[1] => _exec_post), Array ([0] =>
$myQuery = "INSERT INTO `cs_social_alerts` (email) VALUES ('test#test.com')";
mysql_query($myQuery);
debug_print_backtrace()
?>
)) called at [/var/sites/c/*****.com/public_html/wp-includes/plugin.php:192]
#4 apply_filters(the_content,
$myQuery = "INSERT INTO `cs_social_alerts` (email) VALUES ('test#test.com')";
mysql_query($myQuery);
debug_print_backtrace()
?>

Use the PHP function debug_print_backtrace() to find out where your code is being called from.

Try a PHP Data Object(PDO). Using the mysql_* functions are obsolete.
These variable initializations should be defined in an ini file that you use php_parse_ini() to get the data from.
<?php
$host = "host=localhost";
$name = ";dbname=name_of_db";
$user = "user";
$pass = "pass";
$conn = new PDO("mysqli:".$host.$name,$user,$pass);
$stmt = $conn->prepare("INSERT INTO `cs_social_alerts` (email) VALUES (:email)");
$stmt->bindParam(':email', $email);
$stmt->execute();
Also, if you want to know if this code is getting run more than once. Try setting a $_SESSION variable. I.E. $_SESSION['count'] = 0; Then right before execute() put $_SESSION['count']++; Finally, dump the value of $_SESSION at the end of your code to determine what the value is.
var_dump($_SESSION);die();

I had the same problem, and it was chrome fault!
I clear the sessions, cookies, cache, all data application and it works.

Have you tried another browser? I had plenty of bad experiences because some extensions that I had in my browser were requesting the page one more time.
Even if that's not your problem, I think you should check for external factors, as this code cannot insert two rows. Unless, of course, it's being called twice.

Related

PHP INSERT into creates Database error

I am attempting to create a function that will insert items (and will do the same to edit) items in a database through a form. I have the form and the PHP - and when I run the function, I get the correct database name to pull and the variable names to pull along with the values I input, but I then see a database error? Any help would be great (I'm still newer to PHP really and pulling out some hair)
Config File:
$hostname = 'localhost';
$username = 'DEFINED';
$password = 'DEFINED';
$database = 'DEFINED';
$table = 'recipes';
require('../config.php');
$link = mysql_connect($hostname,$username,$password);
mysql_select_db($database,$link);
/* Get values and submit */
$rid = mysql_real_escape_string($_POST['rid']);
$name = mysql_real_escape_string($_POST['name']);
$category = mysql_real_escape_string($_POST['category']);
$tags = mysql_real_escape_string($_POST['tags']);
$search_tags = mysql_real_escape_string($_POST['search_tags']);
$description = mysql_real_escape_string($_POST['description']);
$description2 = mysql_real_escape_string($_POST['description2']);
$recipeAbout = mysql_real_escape_string($_POST['recipeAbout']);
$ingredients_1 = mysql_real_escape_string($_POST['ingredients_1']);
$directions_1 = mysql_real_escape_string($_POST['directions_1']);
$query = "INSERT INTO $table (name, category, tags, search_tags, description,description2, recipeAbout, ingredients_1,directions_1) VALUES ('$name','$category','$description','$description2' $tags','$search_tags','$description','$recipeAbout','$ingredients_1','$directions_1')";
echo $query;
Besides the missing comma in '$description2' $tags' => '$description2', $tags' which you said had been added afterwards, and signaled by Ryan: there's also a missing quote, so change it to '$description2', '$tags' and having 2x '$description' variables, remove one.
VALUES
('$name','$category','$tags','$description','$description2', '$search_tags','$recipeAbout','$ingredients_1','$directions_1')";
However, the most important part to querying, is that you must use mysql_query() which you are not using => mysql_query() which is why data isn't being inserted, once you've fixed the syntax errors.
mysql_query() is the essential part.
Add the following to your code:
if(mysql_query($sql,$link)){
echo "Success";
}
else{
echo "Error" . mysql_error();
}
Plus, use prepared statements, or PDO with prepared statements.
You're using a deprecated library and open to SQL injection..
Plus make sure you have assigned $table to the table you wish to enter data into. It's not shown in your question.
You also did not show what your HTML form contains. Make sure that you are using a POST method and that all elements are named with no typos.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
Sidenote: Error reporting should only be done in staging, and never production.
EDIT: and using mysqli_
As a quick test, try the following and replacing the values in the line below with your own.
<?php
$link = mysqli_connect("host","username","password","database")
or die("Error " . mysqli_error($link));
$table = "recipes";
$name = mysqli_real_escape_string($link,$_POST['name']);
mysqli_query($link,"INSERT INTO `$table` (`name`) VALUES ('".$name."')")
or die(mysqli_error($link));
?>
If that still does not work, then you need to check your database, table, column name(s), including types and column lengths.
Lot's of stuff wrong here...
You're missing a quote on the second of these two items, as well as either a string concat or a comma: '$description2' $tags'
You've also got your order messed up for tags, search tags, and description 1/2.
$description is in there twice (you have 9 columns defined and 10 values in your statement)
You don't seem to have declared a value for $table
As Fred -ii- has pointed out in his answer, you're missing mysql_query() to actually run it. I assumed you have it further down in your code, but it's missing from the post, which is causing some confusion...
Also, consider updating to use mysqli instead of mysql functions.
what are you echoing $query for?
You do not have any reason to do that except if you just want to use it as a string variable.
it should be mysql_query($query);
What is the exact "database error" error you are getting?
I suggest reading this article about PDO
If you can't insert the data correctly, this might be your problem too.

php insert data from fetch array to other table on version 5.4

I have moved to IIS 8 in PHP 5.4. I am trying to collect data from a table and insert them to a different one, i know my code is correct, but seems to be not working, probably because of the php version, can anyone help me?
here's my code
$query = odbc_exec($conn, "SELECT * FROM member");
while($rows = odbc_fetch_array($query)) {
$querystring = "INSERT INTO oldusers (username, password, regdate) VALUES ('$rows['userid']', '$rows['passwd']', '$rows['registdate']')";
$query2 = odbc_exec($conn, $querystring);
odbc_free_result($query2);
//echo $rows['userid']." ".$rows['passwd']." ".$rows['registdate']."<br>";
}
thanks in advance.
instead trying to insert one by one record, better to insert like below:
INSERT INTO oldusers (username, password, regdate) SELECT userid,passwd,registdate FROM member
for more information :http://dev.mysql.com/doc/refman/5.5/en/insert-select.html
You're placing $rows['passwd'] inside of a double-quoted string. Instead you should do:
$str = "some sql $rows[passwd] rest of sql"; // notice the absence of single quotes
or:
$str = "some sql {$rows['passwd']} rest of sql";
or (I think this way is most readable):
$str = 'some sql' . $rows[passwd] . ' rest of sql';
If your column contains text you'll need to add surrounding single quotes where necessary.
Having said all that, you should instead use parameterized queries (if your database supports it) as it's safer (from SQL injection). If that's unavailable you will at the very least need to escape the data before concatenating it to the string.

php app to verify login

Trying to understand how to process a form in php that logs in. It seems clumsy, hopefully there is a better way.
Let's say the user login is userid and password.
If they enter the information on the form, I jump to the next page:
<?php
if (isset($_POST["id"])) {
$con=mysqli_connect("localhost","user","pw","db");
$codeFile = $_POST["filename"];
$id = $_POST["id"];
$fname = $_POST["fname"];
$lname = $_POST["lname"];
$res = mysqli_query($con, "SELECT COUNT(*) from users where id='$id' and fname='$fname' and lname='$lname'");
$row = mysqli_fetch_array($res);
$count = $row[1];
if ($count == 1) {
header("submit.php");
die();
}
$res = $con->query('INSERT INTO log values ($id, now(), $codeFile)');
}
?>
The above code should theoretically only jump to submit.php if exactly one row comes back because there is a matching user. It does not seem to work.
how do I request the first column back? It has no name because it is not a named column.
I cannot believe how many statements it takes to get one simple query done, is there any better way in PHP? Java servlets has some nifty shortcuts such as an integer return code with the number of affected lines, among other things.
if this works, I want to do an insert. It would of course be better to do a combined statement and base the test on the number of lines inserted (1 or 0)
$res = $con->query('INSERT INTO log values ($id, now(), $codeFile)');
Is there any way of combining this into a single query that returns true if it succeeds?
I suggest you either use SELECT * or the actual columns themselves instead of COUNT(*)
For example: SELECT id,fname,lname from table
Yet, I suggest you go about it this way:
Instead of:
$row = mysqli_fetch_array($res); $count = $row[1];
do:
$count = mysqli_num_rows($res); if($count==1){...}
For example and adding mysqli_real_escape_string() for added security (more under Footnotes below)
Sidenote: I'm under the impression that if the query doesn't meet the criteria, that you would like users to be redirected to submit.php and if it does meet it, to do an INSERT.
If so, I modified the method. Plus, using header("submit.php"); is incorrect.
The proper way is header("Location: http://www.example.com");
Another thing before passing on to the code.
This line should use quotes around the values and double quotes to wrap it with:
$res = $con->query('INSERT INTO log values ($id, now(), $codeFile)');
as in:
$res = $con->query("INSERT INTO log values ('$id', now(), '$codeFile')");
NOTE: Try and use actual columns to insert into, it's better.
Plus, $res will not execute since there is no condition set to it. Either remove $res = or add
if($res){
echo "DB insertion was successful.";
}
The code:
<?php
if (isset($_POST["id"])) {
$con=mysqli_connect("localhost","user","pw","db");
$codeFile = mysqli_real_escape_string($con,$_POST["filename"]);
$id = mysqli_real_escape_string($con,$_POST["id"]);
$fname = mysqli_real_escape_string($con,$_POST["fname"]);
$lname = mysqli_real_escape_string($con,$_POST["lname"]);
$res = mysqli_query($con, "SELECT * from users WHERE fname='$fname' AND lname='$lname' AND id='$id'");
$count = mysqli_num_rows($res);
// if successful login, INSERT INTO...
if ($count == 1) {
// NOTE: Try and use actual columns to insert into, it's better.
$res = $con->query("INSERT INTO log values ('$id', now(), '$codeFile')");
if($res){
echo "DB insertion was successful.";
}
}
// if not successful, redirect.
else {
header("Location: submit.php");
exit();
}
} // end brace for (isset($_POST["id"]))
?>
Footnotes:
Your present code is open to SQL injection. Use prepared statements, or PDO
Passwords
I noticed that you may be storing passwords in plain text. This is not recommended.
Use one of the following:
CRYPT_BLOWFISH
crypt()
bcrypt()
scrypt()
PBKDF2
PBKDF2 on PHP.net
PHP 5.5's password_hash() function.
Other links:
PBKDF2 For PHP
You can use the mysqli->affected rows :
http://us1.php.net/manual/en/mysqli.affected-rows.php
you can use LIMIT in your query to return only one result, although it's bad practice if you're getting back a login query, there should be only one anyway.
as to why your code doesn't work, It's hard to say, it depends what comes back from your database.
You'll need to debug $count and see what actually comes out, and work from there.
Finalyl, as far as I know it's not possible to run two queries on the same line, You'll need two inserts for two tables.(table log and table value)

Data is not being inserted into second table (MYSQLi)

I am using the code below that uploads a file and inserts data into the "Image" table using mysqli:
<?php
session_start();
$username="xxx";
$password="xxx";
$database="mobile_app";
$mysqli = new mysqli("localhost", $username, $password, $database);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
$result = 0;
//UPLOAD IMAGE FILE
move_uploaded_file($_FILES["fileImage"]["tmp_name"], "ImageFiles/" . $_FILES["fileImage"]["name"]);
$result = 1;
//INSERT INTO IMAGE DATABASE TABLE
$imagesql = "INSERT INTO Image (ImageFile) VALUES (?)";
if (!$insert = $mysqli->prepare($imagesql)) {
// Handle errors with prepare operation here
}
//Dont pass data directly to bind_param store it in a variable
$insert->bind_param("s", $img);
//Assign the variable
$img = 'ImageFiles/' . $_FILES['fileImage']['name'];
$insert->execute();
//RETRIEVE IMAGEID FROM IMAGE TABLE
$lastID = $mysqli->insert_id;
//INSERT INTO IMAGE_QUESTION DATABASE TABLE
$imagequestionsql = "INSERT INTO Image_Question (ImageId, SessionId, QuestionId) VALUES (?, ?, ?)";
if (!$insertimagequestion = $mysqli->prepare($imagequestionsql)) {
// Handle errors with prepare operation here
}
$sessid = $_SESSION['id'] . ($_SESSION['initial_count'] > 1 ? $_SESSION['sessionCount'] : '');
$insertimagequestion->bind_param("sss", $lastID, $sessid, $_POST['numQuestion'][$i]);
$insertimagequestion->execute();
//IF ANY ERROR WHILE INSERTING DATA INTO EITHER OF THE TABLES
if ($insert->errno) {
// Handle query error here
}
$insert->close();
if ($insertimagequestion->errno) {
// Handle query error here
}
$insertimagequestion->close();
}
}
?>
So for example if I insert 2 images "cat.png" and "dog.png" into "Image" Database table, it will insert it like this:
ImageId ImageFile
220 cat.png
221 dog.png
(ImageId is an auto increment)
Anyway what I want to do is that when a file is uploaded, not only is the data inserted into the table above, but I want to also be able to retrieve the ImageId that was inserted above and place it in the "Image_Question" table below so it would be like this:
ImageId SessionId QuestionId
220 cat.png 1
221 dog.png 4
The problem is that it is not inserting any data into the second table "Image_Question", does anyone know why it is not inserting any data? There is no errors in the php file.
To upload a file, the user selects a file for the ajax uploader in the "QandATable.php" page, when the user clicks on upload, using AJAX it will go onto the imageupload.php page and does the uploading there. So the problem I have is that no errors will appear as they are on seperate pages.
First, save the insert ID gained from your record addition (after the $insert->execute):
$lastID = $mysqli->insert_id;
Then reference $lastID later.
To pull up my comment from below:
$lastID = $insert->insert_id;
I think it's to do with swapping the handle names around - $mysqli, $insert etc.
Hope I read the question correctly...
Check for 500 Error responses in Firebug -> Net tab/Chrome Developer tools -> Network tab . Even if nothing is returned as text, this will help you debug a syntax/semantic error as opposed to a logical error.
Firstly, what happens when you echo $lastID? Do you get a value output to the screen?
If not, we need to fix that first so that $lastID is returning the correct value.
Your insert code appears to be correct.
You should get the Last inserted ID from first table and insert into your 2nd table (Image_Question) .
I Don't know the PHP coding, but this task is simple as well.Because this operation will be executed inside DAO class.So, No matter whether it is PHP or JAVA.
If the second insertion fails, then
if ($insertimagequestion->error) {
// Handle query error here
echo $insertimagequestion->error;
}
This should tell you what the Error being thrown from the execution of the statement is.
Your PHP code seems fine, the error could be due to a Foreign key constraints or any other constraints on your DB Tables.
PS: I think you should validate the type of files you allow to be uploaded so people can't upload *.php or *.js files, this can lead to catastrophic XSS attacks.
Also try to avoid using the same filename as uploaded by the user, you may want to prefix with some random variable, so you can now have
//notice uniqid(time()) for randomness, also move the declaration of $img higher
//Assign the variable
$img = "ImageFiles/" . uniqid(time()) . $_FILES["fileImage"]["name"];
move_uploaded_file($_FILES["fileImage"]["tmp_name"], $img);
...
//Dont pass data directly to bind_param store it in a variable
$insert->bind_param("s", $img);
Bind with mysqli works with references to variables. I dont think your last argument in the second bind command references the way you expect it to.
Assign the the last argument $_POST['numQuestion'][$i] to a variable and use this variable in the bind method call. I am guessing this is either not defined, evaluating to null, and the bind is failing since you can't bind a null as a string or bind cannot use a multidimensional array since itexpects a variable passed as reference.
Try this:
//Below will set a default value of empty string if the POST variable is not set
$postVar = isset($_POST['numQuestion'][$i])?$_POST['numQuestion'][$i]:'';
$insertimagequestion->bind_param("sss", $lastID, $sessid, $postVar);
After doing this, if you see entries in the DB with a '' in the QuestionId column, $_POST['numQuestion'][$i] isn't being set and you have something wrong elsewhere in your code having nothing to do with DB access.
Tried to figure out where could be the failure.
There is no problem with second query and you get successfully last insert id. I used static values for the variables for second query it worked fine. Even you can hardcode values n check out.
Take care of the foll:
Does bind params get the all the values?
print_r() $lastID, $sessid, $_POST['numQuestion'][$i]
This Will not create problem unless database has contraints of not accepting empty or null values.
Make use of the check condition to find where its going wrong.
if (!$insertimagequestion = $mysqli->prepare("$imagequestionsql")) {
// Handle errors with prepare operation here
echo "Prepare statement err";
}
if ($insert->errno) {
// Handle query error here
echo "insert execution error";
}
Though its an ajax you can use Developer Tool of Chome to debug ajax requests.
Press F12 to open the Developer Tool in Chrome
Go to Network Tab >> Perform action for ajax requests to be sent on your form >> you can find the ajax requests sent >> click on it >> Click on the "Response" Tab you will find the error if you have
echoed or the response. So, echo error and print_r() to help debugging

ON DUPLICATE KEY UPDATE creating new records

I am having problems with the following code, it seems to work and creates the records just fine, the problem is each time I hit submit, instead of it updating the record it just creates a new one. If I turn off auto incremental for the primary key it updates the record just fine but then doesn't create any new ones, it seems either one or the other :-S
<?php
$query = mysql_query("
INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
('$_POST[cf_id]','$_POST[cf_uid]','$_POST[emailformname]','$_POST[datesent]')
ON DUPLICATE KEY UPDATE
datesent='$_POST[datesent]';
") or die(mysql_error());
?>
did you already try to echo your query string? guess the variable replacement inside it is wrong. try something like that for debugging:
<?php
$sql = "INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
('{$_POST['cf_id']}','{$_POST['cf_uid']}','{$_POST['emailformname']}','{$_POST['datesent']}')
ON DUPLICATE KEY UPDATE
datesent='{$_POST['datesent']}'";
echo $sql; // for debugging
$query = mysql_query($sql) or die(mysql_error());
?>
Note the corrected variable names above. (curly braces around it, quotes around the array index)
I can't imagine it's the problem, but does the same thing happen when you cast the ID to an int and leave out the quotes?
<?php
$query = mysql_query("
INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
(" . (int) $_POST['cf_id'] . ",'$_POST[cf_uid]','$_POST[emailformname]','$_POST[datesent]')
ON DUPLICATE KEY UPDATE
datesent='$_POST[datesent]';
") or die(mysql_error());
?>
By the way, you really shouldn't use your $_POST variables in your query without mysql_real_escape_string or better yet, use prepared statements (PDO or mysqli).

Categories