Mysql PHP Arbitrary Increment - php

I'm trying to increment +1 impression every time an ad is displayed on my site, however the variable increments +2 to +3 arbitrarily. I've removed everything that's working correctly and I made a page with only this code in it:
<?php
require "connect_to_mydb.php";
echo 'Hello***** '.$testVariable=$testVariable+1;
mysql_query("UPDATE `imageAds` SET `test`=`test`+1 WHERE `id`='1'");
?>
Every time the page is refreshed the, test increments arbitrarily either +2 or +3 and my page displays Hello***** 1 (Just to show its not looping). Access is restricted to this page so it's not other users refreshing the page.
Also, id and test are int(11) in the DB.
My DB required connection has nothing in it that would interfere.
Edit
Here is an updated code:
<?php
require "connect_to_mydb.php";
mysql_query("UPDATE `imageAds` SET `test`=`test`+1 WHERE `id`='1'");
$sql = mysql_query("SELECT * FROM imageAds WHERE id='1' LIMIT 1");
$check = mysql_num_rows($sql);
if($check > 0){
$row = mysql_fetch_array($sql);
echo $row['test'];
}
?>
Increments by +2 everytime
Edit
This is whats in connect_to_mydb.php
<?php
$db_host = "*************************";
$db_username = "*********";
$db_pass = "**********";
$db_name = "**************";
mysql_connect("$db_host","$db_username","$db_pass") or die ("could not connect to mysql");
mysql_select_db("$db_name") or die ("no database");
?>

Either there's a bug in MySQL's implementation of UPDATE, or you're doing something wrong in some code you haven't posted.
Hint: It's very unlikely to be a bug in MySQL. Other people would have noticed it.
From what you've shown, it looks like your page is being loaded multiple times.
This attempt to prove that the code is only being called once doesn't prove anything:
echo 'Hello***** '.$testVariable=$testVariable+1;
This will always print the same thing (Hello***** 1) even if you open this page multiple times because the value of $testVariable is not preserved across seperate requests.

This +2/+3 error is occurring only with Chrome and my Mobile Android browser and the code is solid. I looked to see if there is any issue with Chrome sending more than one http request (thx user1058351) and there is which is documented here:
http://code.google.com/p/chromium/issues/detail?id=39402
So since this way was unreliable I just completed a work around that is solid. Instead of including a PHP file that updates the amount of ad impressions on reload, I now have it so when the page loads, an AJAX request is sent to a separate PHP file which updates the ad stats and returns the appropriate data. The key I think is to send it through the JS code so only one http request can be sent to increment the data.
Thank you to all who responded especially user1058351 and Mark Byers (not a bug in MYSQL but possibly appears to be a bug in Chrome).

Related

Wait between fetching value one by one in data base

<?php
$host= "localhost";
$user= "xxxxxx";
$pass= "xxxx";
$db="xxxxxxx";
$connect= mysql_connect($host,$user,$pass);
if (!$connect)die ("Cannot connect!");
mysql_select_db($db, $connect);
$result = mysql_query("
SELECT
*
FROM
values
");
if($result){
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
$url = $row['value'];
echo '<li><iframe src="http://xxxxxxx.xxxx/xxxx.php?value='.$url.'" width="300" height="100" scrolling="no" frameBorder="0""></iframe></li>';
}
}
?>
this is my php code I am using to get values from database. I want to use a time delay in each of the value.
like
http://xxxxxxx.xxxx/xxxx.php?value='.$url.'
wait 5 sec
http://xxxxxxx.xxxx/xxxx.php?value='.$url.'
wait 5 sec
and so on.
Is there any way I can do that.
Thanks.
wrong answer: use sleep(5) inside while().
right answer:
a) you should not use mysql_* functions
b) if you need a delay, get all rows, then output them one by one using JS.
OR:
c) again, using JS and ajax, query for new row every 5 seconds
If you'll stick to wrong answer, your script will die of timeout at ~6th row (in default php install)
You should understand client/server architecture better:
mysql query and your php-code is a server-side, it will not return any output to browser (your visitor), until its end, and you don't want your visitors to wait 30 or 300 seconds for the server to reply.
so only option you have is: query for new image every 5 seconds, or query them all and iterate over them.
There are many jquery/javascript tutorials on that subject.

Posting to SQL with JQuery, Ajax and PHP

I have run into a small problem which I can't seem to figure out.
I am creating an application that when a user clicks a button, depending on which button they click, it will post a number into the database.
There are 9 numbers (0-9) and if they click 0 then 0 gets put into the database, if they click 1 then 1 gets put into the database, etc...
I have an onclick call using JQuery and Ajax to submit the data silently:
$(function(){
$('#1A').click(function(e) {
alert("You clicked 1A");
var poll_ans = 1;
$.ajax
({
url: 'postpoll.php',
data: {"pollAns": poll_ans},
type: 'post',
success: alert("Submitted " + poll_ans)
});
});
});
This works fine, and when I click the DIV with ID 1A I get the alert, and the "Submitted!" alert.
However, it does not post to the SQL Database. When I test the postpoll.php file by itself setting the variables in the URL it seems to load indefinitely.
Here is my code:
postpoll.php
<?php
session_start();
$mysqli=mysqli_connect("***","***","***","***");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(isSet($_POST['pollAns']))
{
$answer=intval($_POST['pollAns']);
$query = "INSERT INTO test VALUES '$answer'";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
}
?>
Not sure what the problem is here - I am sure I missed something, and it's probably a simple solution!
Also, a side note - I eventually want to make it where the can only vote once, would the best way to accomplish this to simply set a cookie, then check if that cookie is present before posting? I know they could circumvent this by clearing their cookies, but it's not a problem.
SOLUTION:
It would appear that the culprit was CloudFlare. After checking on the httpd.conf file it showed that the sql connection was timing out. This was due to the fact that I was trying to connect to the DB using the actual URL, which is routed through CloudFlare's servers. In order to get to the actual physical server, I ended up using the IP. You can also add a DNS record that points to the IP and make sure you have it not being routed through CloudFlare.
Suggested Action in the Future: Remember that you are using CloudFlare!
When you establish the connection you name it $con, then you try to query using the variable $mysqli. Change $con to $mysqli when establishing the connection. I also changed VALUE to VALUES and added single brackets around $answer.
<?php
session_start();
$mysqli=mysqli_connect("***","***","***","***"); // Change from $con to $mysqli
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(isSet($_POST['pollAns']))
{
$answer=intval($_POST['pollAns']);
$query = "INSERT INTO test VALUES '$answer'"; // Add single brackets around $value and changed VALUE to VALUES
$result = $mysqli->query($query) or die($mysqli->error.__LINE__); // Here you are using $mysqli to perform query
}
?>
Make sure your login credentials are correct. Also you have not properly handled the success and error events in your ajax request and alert the error message you get.
Try "isset" instead of "isSet", also set a session in the if statement. if (isset($_POST['pollAns'])) { $_SESSION['verify'] = "true"; } then echo $_SESSION['verify'] to see if the page is even getting to the sql statement.
See if changing the $mysqli->query($query) to this changes anything: $result = mysqli_query($mysqli, $query); (this shouldn't, I know that both ways work)
Also, a side note - I eventually want to make it where the can only vote once, would the best way to accomplish this to simply set a cookie, then check if that cookie is present before posting? I know they could circumvent this by clearing their cookies, but it's not a problem.
You can check the table first to see if that users IPAddress is listed:
$sq = "select * from test where IPAddr = '".$_SERVER['REMOTE_ADDR']."'";
$qu = mysqli_query($mysqli,$sq);
// if it does then the mysqli_num_rows will return 1 or greater.
if (mysqli_num_rows($qu) == 0) {
$query = "Insert into"...
}
It would appear that the culprit was CloudFlare. After checking on the httpd.conf file it showed that the sql connection was timing out. This was due to the fact that I was trying to connect to the DB using the actual URL, which is routed through CloudFlare's servers. In order to get to the actual physical server, I ended up using the IP. You can also add a DNS record that points to the IP and make sure you have it not being routed through CloudFlare.
Suggested Action in the Future: Remember that you are using CloudFlare!

Cannot name a php $_SESSION the id value

I'm trying to make a voting system for a database currently records are rendered in php on screen with images for an up or down vote. When clicked they run the php scripts upvote.php or downvote.php respectively, they pass the id value (integer of the record being manipulated.
Currently it works, the scripts increment and decrement the records votes value as intended. I was, however, trying to stop a user doing this multiple times for one record. I was trying to achieve this by using a session and naming it the value of the id and before altering the votes value checking if the session for that id has been set.
I am going to use my 'upvote.php' as my example:
//Upvote Script
//begin session
session_start();
//database connection credentials import
include("../scripts/connection_variables.php");
//connect to mysql or display error
#mysql_connect("$db_host","$db_username","$db_pass") or die ("Could not connect to the database, please try again shortly. If problem persists please refer to help then contact support.");
//select database or or display error
#mysql_select_db("$db_name") or die ("Could not connect to the database, please try again shortly. If problem persists please refer to help then contact support.");
//collect id
$id = $_GET['id'];
//check if user has already voted for this
if(isset($_SESSION[$id])) {
//session has been set for this id, so don't execute the script
exit();
}else{
//set the session
$_SESSION[$id] = "The punniest thing about puns is that they are really punny.";
//increment the votes value
$query = "UPDATE punniest_database SET votes= 1 + votes WHERE id='$id'";
mysql_query($query);
}
The default serializer used for sessions cannot handle numeric-only keys. It also emits a warning message during shutdown, you should see it in your logs (assuming you have logging enabled, look for Unknown).
Older serialize handlers cannot store numeric index nor string index contains special characters
(quote from link below)
You can test it with the following script, save it somewhere and refresh a few times:
<?php
session_start();
$_SESSION[time()] = true;
var_dump($_SESSION);
The most portable solution is prefixing the keys with a static string. Alternatively you can change the serialize handler used for sessions.

html button to reset field in mysql database using php

Kinda new to mysql and php
I have a hit counter for each page on my site and a private page that list all pages and hits.
I have a button that will reset all pages to zero and next to each page listing I have a reset button that will reset each page individually. This all was using a text file but now I am swtching to mysql database. I have coded the "RESET ALL" button to work but can not get the individual page buttons to work.
the processing code is:
if($_POST[ind_reset]) {
$ind_reset = $_POST[ind_reset];
mysql_connect("server", "username", "password") or die(mysql_error());
mysql_select_db("database") or die(mysql_error());
$sql = 'UPDATE counters SET Hits =\'0\' WHERE Page = \'$ind_reset\';';
}
and the html form code is a string:
$page_reset = "<form id='Reset' action='counter_update.php' method='post'>
<button type='submit' name='ind_reset' value='$formPage'>RESET</button>
</form>";
Let's start with the first thing:
if($_POST[ind_reset]) {
should be
if($_POST['ind_reset']) {
It works without quotes because PHP is silently correcting your error. If you turned error reporting to E_ALL, you would get to see the error message.
One thing that you need to consider is that you can never trust POST data to be what you think it's supposed to be. Maybe you put in a typo. Maybe a hacker is sending you fake POST data. Whichever it is, it will mess up your code if the wrong thing gets put in that database update. For this reason, instead of simply plugging in that POST value into your database, you should have a checker to make sure that the value is a valid one. When I do things like this, I make an array of possible values and use only those values when updating or inserting into the database. Example:
$pages = array('value_on_page'=>'value_put_in_database',
'xyz'=>'thing_in_database_2');
//the valid things to post are either 'value_on_page' or 'xyz',
//but what goes into the database are the values those keys point to
//e.g. if $_POST['ind_reset'] == 'xyz', $ind_reset will be 'thing_in_database_2'
$key = $_POST['ind_reset'];
if(!isset($pages[$key])) {
//if that posted value isn't a key in the array, it's bad
error_log('Invalid posted page'.$key);
} else {
//this is a valid posted page
$ind_reset = $pages[$key];
//** do the database stuff right here in this spot **//
}
Now, for the reason your posted code doesn't work, you are missing the final, crucial part of doing a database query: the part where you actually run the query.
$conn = mysql_connect("server", "username", "password") or error_log(mysql_error());
mysql_select_db("database") or error_log(mysql_error());
$sql = 'UPDATE counters SET Hits =\'0\' WHERE Page = \'$ind_reset\';';
mysql_query($sql, $conn) or error_log(mysql_error());
I hope you have noted that I replaced "die" with "error_log." If you do error_log(mysql_error(), 1, 'youremail#example.com'), it will email it to you. Otherwise, as with in my examples, it gets put into wherever your system's error log file is. You can then have a nice history of your database errors so that, when you inevitably return to StackOverflow with more questions, you can tell us exactly what's been going on. If you use a file, just make sure to either rotate the error log file's name (I name them according to the day's date) or clear it out regularly, or it can get really, really long.
Using the mysqli code you posted in your comment is a better idea than the mysql_* functions, but you don't quite have it correct. The "bind_param" part sticks your variable into the spot where the question mark is. If your variable is a string, you put "s" first, or if it's an integer, you put "i" first, etc. And make sure you close things once you're done with them.
$db = new mysqli("server", "username", "password", "database");
if(!$db->connect_errno) {
$stmt = $db->prepare("UPDATE counters SET Hits = '0' where Page = ?");
$stmt->bind_param('s',$ind_reset); //assuming $ind_reset is a string
if(!$stmt->execute()) {
error_log($stmt->error);
}
$stmt->close();
} else {
error_log($db->connect_error);
}
$db->close();

Updating MySQL using SESSION variables via a jquery javascript function

I currently have a javascript file 'score.js' which makes use of jQuery.js, which is being called correctly via a link. The code in score.js is:
function originalUpdateScore(answer,correct){
if (answer == correct)
{
$.post('updateScore.php');
}
window.location.reload(true);
}
This function calls 'updateScore.php':
<?php
include("dbstuff.inc");
$con = mysqli_connect($host, $user, $passwd, $dbname)
or die ("Query died: connection");
$updateScore = "UPDATE `user` SET `tempScore`=`tempScore`+1
WHERE (user.Username='$_SESSION[logname]')";
mysqli_query($con, $updateScore);
?>
However the database is not being updated correctly. If I replace the line:
$updateScore = "UPDATE `user` SET `tempScore`=`tempScore`+1
WHERE (user.Username='$_SESSION[logname]')";
with:
$updateScore = "UPDATE `user` SET `tempScore`=`tempScore`+1
WHERE (user.Username='123pf')";
Where 123pf is the value that the SESSION variable contains in the php file calling the javascript it updates correctly. Why does using the session variable not work? Am I calling it incorrectly in the query?
Thanks in advance.
Are you calling session_start anywhere inside updateScore.php?
If you haven't started the session I do not believe that session variables will be available.
also, do you have complete control over $_SESSION['logname']? If not, someone could easily change their logname to inject SQL and damage/compromise your database. For example, if they were able to set their logname to be this, you could lose your user table:
$_SESSION['logname']="'; DROP TABLE user;-- ";
You're opening yourself right up to cheaters by playing like this. Under this scenario, any user could visit updateScore.php at any time to increase their stats, since that script neither checks their answer nor checks for a token that the JS builds to say the score is ok. It is a bad idea to keep this kind of logic on the front-end (javascript) without also having it verified on the back end (PHP); javascript & AJAX are very helpful shortcuts that can improve user experience, but they cannot be trusted as sole validity checkers.
It's probably just a transcription error, but the code that you have shown in your question uses $_SESSION[logname], it should be $_SESSION['logname'].

Categories