9

I've got a simple code below. After it's run once, it inserts results twice into the mysql database.

if it run twice or request twice base on 1 refresh on the page, why the output is just 1 result?

I have been googling for the whole day and struggling to resolve this issue. However, I failed to figure out what is wrong with this code. The code runs perfectly on localhost, but after it's moved to the server, the problem pops up. Has anyone faced something like this before? How can this problem be resolved?

FULL CODE:

<?php
$db=mysql_connect('localhost','zzzzzzz','xxxxxx') or die('Unable to connect.'.mysql_error());
mysql_select_db('test',$db) or die(mysql_error($db));

$sql="INSERT INTO test_table(value,insert_time) VALUES ('testing','".time()."')";
$result=mysql_query($sql);
echo "result=".$result;

$select="select * from test_table";
$rs=mysql_query($select);
while($row=mysql_fetch_array($rs)){
echo $row["test_id"]." -- ".$row["value"]." -- ".$row["insert_time"]."<br />";
}
?>

RESULT:
result=1
1 -- testing -- 1298185509

BUT IN DATABASE:
test_id , value , insert_time
1 , testing , 1298185509
2 , testing , 1298185511

11
  • 7
    Have you examined your HTTP log to ensure that it really IS only running once? The browser might be submitting more requests than you expected. This is especially true if your page doesn't output meaningful html (which I don't see the above doing). In general, you cannot rely on the number of times a browser submits a GET request; they should be repeatable with no bad side effects (idempotent) Commented Feb 20, 2011 at 7:53
  • have you tried changing VALUES to VALUE and the field name, value to value Commented Feb 20, 2011 at 7:55
  • 2
    Be particularly wary of browser debugging tools such as Firebug, which may issue a request more than once Commented Feb 20, 2011 at 7:57
  • 2
    The time difference of two seconds is rather a sign that there are actually two HTTP requests. Commented Feb 20, 2011 at 8:09
  • But..do you clear the DB after every page load? because in SELECT you have a while loop, so: 1st load: you insert one record and then fetch all records in db (without a where condition) - there's just one record. 2nd load: you insert ONE record, and fetch ALL - thre's 2 records. 3rd load: you insert one record, you fetch 3 now. And so on..You're not inserting twice because "insert = " echoes just once, from what I see in your code Commented Feb 20, 2011 at 8:51

14 Answers 14

21

I'm facing the same issue as you, the problem only occus when I use Opera or chrome.

For my case, I have an .htaccess to point every thing to the index file. Naturally the browser will request the script twice, once for the script it self, the other is for the favicon.

The fix: Run the insert query only for a specific request, not for any request that lands on your site.

Sign up to request clarification or add additional context in comments.

2 Comments

Endy Jasmi, this is your only answer and you haven't been back to this site in over 3 years, but I've been pulling my hair out over this bug, and you solved it. Thank you.
It would be great if you could add the lines you added to your htaccess file
1

There're many reasons to cause this, so I would suggest you using the best practice:

If you're creating a new record in your DB, you should init the logic with a POST request.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // …
}

The non-code problems should be easily avoided now: .htaccess thing, Firebug thing, ads tracking thing...

1 Comment

@nicng let me know if this can't fix
1

This problem may also be arising due to you may be mixing the GET and POST

Or

you may have downloaded online template which is may be making an background ajax call before the page is submitted.

Please have a look and if you find a solution or if there is any other problem let us know.

Comments

1

Code is fine.

Try to change browser. If still not worked.

Restart server Still not

Try to write in another file outside of project as single script.

It will work.

I tried your code its working on my system.

Comments

1

I had this issue happening on Chrome Browser and found 2 ways to solve it;

  1. You can add a captcha control on your form. This prevents it from running twice and entering that extra data line to SQL.You can get the captcha code from here;

click for Captcha information

  1. Create a session control by starting a session on your form page;

    $_SESSION['formzt']= 0;

And in your POST page use an "if" statement before your insert;

if ($_SESSION['formzt']==0){

$sql="INSERT INTO members (user)
VALUES ('testini')";

if (mysqli_query($conn, $sql)) {
   echo "New record created successfully";
} else {
    echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}

  $_SESSION['formzt']++;

 }

This will prevent it from reinsert.

Comments

0

As you mentioned the problem does not occur when you test locally, only occurs when you deploy in server --- I guess you have Google Adsense in your page. In that case, adsense crawler is crawling your page (sending the second http request to the url)

To avoid this, add following in start of your php file:

if(strpos($_SERVER['HTTP_USER_AGENT'],'Mediapartners-Google') !== false) {
        exit();
}

I had faced similar issue in a script which sends emails. I was getting double emails per action :(

Then, I investigated into the server access log, and discovered the second request per action from this user agent ...

3 Comments

If you do not have adsense, then this solution is not required for you. But, if you had analysed the server access log, you should have found the issue already.
i change the insert value 'testing' to $_SERVER['HTTP_USER_AGENT'], and result, still 2 row has been inserted, but both values is different! Is that means the browser actually request twice and cause the problem? Values as follows: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.59, Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3)
log : $_SERVER['REMOTE_ADDR']
0

Ok, I know that this doesn't make any sense, but I solved removing $.ajax({async:true}); from my js file.

Comments

0

I had the same issue on my site. After debugging I found the root cause. It is Yandex Metrica js library. It calls ajax request to the same page to calculate loading time and some other params.

Do you use it? If not open chrome dev panel and look at http request. May be it is request for favicon or etc.

Comments

0

There is no problem with your code.Firebug or similar tools can make double request sometimes. Also metric scripts (yandex metrica, chartbeat etc) in your page can do same behavior. You should inspect these situations.

To debug it you can log insert requests, and you can inspect it to find what is wrong.

If you are using linux environment ;

Add a log line to your code :

error_log(print_r($_SERVER,true));

Open a console window and type (log directory depends on your sever configuration)

tail -f /var/log/apache/error.log

And then you can call your insert page. At every request you can see what is happening.

Comments

0

I guess this code from index.php which is front-controller for all requests.
When browser fetches page it usually trying to get favicon.ico too. And if favicon is missing, second request is processed your php file again. You can examine this supposition by writing $_SESSION['REQUEST_URI'] to DB.

I recommend do not change data in GET requests and research web server access log from time to time.

Comments

0

Your code seems fine, and it should be probably due to external plugins that you are using, which send a 2nd request each time.


If you are using Google Chrome, it would most likely be due to this bug, https://bugs.chromium.org/p/chromium/issues/detail?id=123121. This bug causes Chrome to redirect every request into index.php, so the PHP script will run twice.

This can be fixed using the following code, as according to website.

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !favicon.ico
RewriteRule .* index.php [L]

You can also debug using debug_print_backtrace: http://php.net/debug_print_backtrace.

debug_print_backtrace() prints a PHP backtrace. It prints the function calls, included/required files and eval()ed stuff.


Alternatively, you can use SQL UNIQUE Constraint to prevent duplicate rows from being inserted in the first place. Find out more at http://www.w3schools.com/sql/sql_unique.asp.


Just a note: There are mysql() have been deprecated, use MySQLi instead.

Comments

0

The solution by Endy Jasmi worked for me. Here is how I edited my .htaccess file.


    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /site2/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /site2/ [L]
    </IfModule>

    # END WordPress

earlier it was like


    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /site2/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /site2/index.php [L]
    </IfModule>

    # END WordPress

Comments

-1

Try this solution in your header html.

<base href="/">

Comments

-2
$result=mysql_query($sql); echo "result=".$result;

It's because you run mysql_query($sql) twice. Try it without echo the $result.

1 Comment

$result stores the output (resource on success, false on error) of the mysql_query method, not a reference to actually running it, as your answer suggests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.