Users not going offline - php

So basically I have this script for my server that keeps all the users up to date on my panel for my .net licensing system, but for some reason some of the users don't go offline when they are most definitely not connected to the server.
Basically every time the user checks in( every minute ) it will update their account with the time they checked in. Then I have the following script to check if the user's check in time is 2 minutes behind the time it is now, so then it will set them offline as they haven't checked in, in 2 minutes.
My problem is, it is working for most users, but like 9% of them don't go offline when checking and there seems to be no errors, unless i'm wrong, can anyone help me out in fixing this simple problem?
PHP SCRIPT:
$SQLGetUsers = $odb -> query("SELECT * FROM Account");
while ($getInfo = $SQLGetUsers -> fetch(PDO::FETCH_ASSOC))
{
$id = $getInfo['id'];
$lastlogon = $getInfo['lastlogon'];
$time = time();
$timeouttime = ($time - 120);
if ($lastlogon <= $timeouttime)
{
$odb->exec("UPDATE Account SET `online` = '0' WHERE `id` = '$id'");
}
$odb->exec("OPTIMIZE TABLE Account");
}
I do know this is a bad script, but it's the only way I personally know of executing this specific command. Thanks to anyone who can help!

Related

How to set query for cron jobs in windows task schedular with php and xampp?

Basically i want if any user will registered himself in system. After 1 month of creation date user should be delete from db automatically.
In my table i have creationDate column. I am done with my creating scheduler for system. its working. I just want to know what query will be set for my kind of thing.
Below is my code for cron.php:
<?php
include 'db.php';
$sql = mysqli_query($conn,'select * from user where createdDate<=CURRENT_DATE - INTERVAL 3 DAY');
$data = mysqli_num_rows($sql);
if($data > 0)
{
while ($row = mysqli_fetch_array($sql))
{
$id = $row['userId'];
$sql = mysqli_query($conn, "DELETE FROM user where userId='".$id."'");
}
}
?>
Follow below method to hit your file/function using powershell
Open Windows Task schedular
Create Basic Task wizard
Set Tigger Option according to your requirement
Set Action to "Start a program"
Set Program/script = powershell
Add arguments command = PowerShell Invoke-WebRequest -Uri http://domainName/functionName -Method GET
Finalize it and then edit trigger with advance setting to set every minutes indefinitely

Check if IP is in database, if not add it and increment a value

I'm building a site that lets users anonymously post messages to a board and rate other messages. Because it's anonymous and doesn't use any kind of user id, when someone clicks to vote up or down on a post, I need to store that post_id and their IP address so they can't vote again.
Here's the system I have in place, it does not work and I don't know why:
mysqli_autocommit($connection, TRUE);
mysqli_query($connection, "UPDATE $tablename SET downvotes = (downvotes + 1) WHERE id = $post_id AND NOT EXISTS (SELECT 1 FROM $table2name WHERE ip = $ip_usr AND post_id = $post_id");
if(mysqli_affected_rows($connection) > 0) {
$insert = mysqli_query($connection, "INSERT INTO $table2name VALUES($post_id, $ip_usr)");
$insert ?
mysqli_commit($connection):
mysqli_rollback($connection);
} else {
mysqli_rollback($connection);
}
I received a tip that instead of using mysqli_autocommit() I should use mysqli_begin_transaction(), however I am using PHP version 5.2 and that function doesn't exist yet, and I have no way of upgrading my PHP version.
The gist of what I'm trying to do is when someone tries to vote on a post, if they haven't voted yet, their vote is made and their IP and that post's id are added into a table. If they have already voted, nothing happens.
Can anyone please help me? Thanks!

PHP MySQL Negative Value (Balance) Issue

I am developing a desktop software where it charge user per execution the main action. For example say it will charge user 0.1$ for per PDF print.
and my software provide multithreading. .
so, if it run single thread it works fine :)
but the problem is if user run multiple thread at one (say 10/20 threads)
it (php) also continues user to allow the server/execution even balance get below zero..
though my php script check whether balance is positive ..
but after user run multiple threads balance become like -5.95$ or -25.75$ etc
and that is a big security/financial issue..
here is the code I am using:
<?php
$strSQL = "Select * from users where Email = '$strUser'";
$return = mysql_query($strSQL, $strDBConn);
$strDBData = mysql_fetch_array($return, MYSQL_ASSOC);
//checking balance
$strBalance = $strDBData['Balance'];
if($strBalance < 0)
{
// if balance 0 then exit so, my software/thread will not process further
mysql_close($strDBConn);
exit('Balance Exceed');
}
//rest of the codes that realted to service executaion
// code that substract the balnce
$dblCost = 0.25;
$strSQL = "Update users set Balance = Balance - '$dblCost' where Email = '$strUser'";
$return = mysql_query($strSQL, $strDBConn);
//rest finising codes
?>
any help/suggestion would be highly appreciated..
thanks in advance.
best regards
I think, this is a quite similar question:
What is equivalent of the C# lock statement in PHP?
First, try to switch away from the old "mysql" to somethin new, maybe some PDO like DB access ;).
Then, for getting around with multi-thread in php, it can be a good idea, to write a file for every userid (!) and lock this file, when there's a request. When file is locked in another thread, wait for x seconds for the file to be unlocked by the locker-thread. If it is not unlocked within time, something went wrong. When in locked-thread all went good, unlock the file after every operation needed.
Theoraticaly you will be good with then till there's a multi-thread soloution in PHP ;)

How do you write a program to automatically modify existing SQL database every x minutes?

I am a PHP/SQL novice user....Finishing off my first PHP website. The question is similar to the initial question found at:
http://forums.phpfreaks.com/topic/266235-modifying-database-after-a-set-time-limit/
but I did not completely understand the answer. Similar to that user, I have an entire column (called status) of a database (called challenge) that can take 3 values for status - 'inactive', 'pending', or 'active'. In the normal flow of website operations, User A will typically click a button (event 1) which creates a new row (with a unique *challenge_id*) in the database and triggers a status of 'pending' in that row. User B can change the status with other clicked buttons, which can set the status to 'inactive' or 'active'.
One undesirable scenario is where USER B does nothing (i.e., no event trigger). In this case, User A is unfortunately stuck, waiting for the status to change from 'pending' to either 'active' or 'inactive' before he/she can click and trigger the next event 1. This situation could occur for example if User B gets tired of the site and does not use it anymore, leaving 'pending' requests unanswered.
Clearly, I can manually alter the SQL, changing any 'pending' status to 'inactive' after a certain time limit. This would be fine at the beginning, but if the site ever became popular, this would take more time. Is there any way to write a non-PHP program to account for this 'no event trigger' scenario where all 'pending' status SQL entries are automatically altered after a certain time limit? Or can PHP do this? I tried writing a php script that would sweep the database every time any user logged in (note: *challenge_id* is created by an event triggered on a different PHP page):
<?php session_start();
if ((($_SESSION['role']) != SHA1('user')) && (($_SESSION['status']) != SHA1('active')))
{
header( 'Location: index.php' ) ;
session_destroy();
} else
include 'connect.php';
$_SESSION['login_id'];
$universaltime = time();
$sqlt = mysql_fetch_assoc(mysql_query("SELECT challenge.challengetime,
challenge.status FROM challenge"); //Selects an array of all values for challengetime
//and status for all users I presume
while ((($universaltime - $sqlt['challengetime']) > 1000) &&
($sqlt['status'] == 'pending'))
{
$sqlt1 = mysqli_query("UPDATE challenge SET $sqlt['status'] ='inactive'");
//Also tried with if instead of while
}
?>
I'm sure my code can be improved...any help would be appreciated greatly! Or do I need to use something other than PHP?
First of all your UPDATE statement is wrong. Assuming that challengetime is of int data type holding unix time values your UPDATE statements should look something like this
UPDATE challenge
SET status = 'inactive'
WHERE status = 'pending'
AND 1000 < UNIX_TIMESTAMP() - challengetime;
It can be and should be run on its own. You don't need to select anything prior to calling it.
Therefore you can change this part
$universaltime = time();
$sqlt = mysql_fetch_assoc(mysql_query("SELECT challenge.challengetime,
challenge.status FROM challenge"); //Selects an array of all values for challengetime
//and status for all users I presume
while ((($universaltime - $sqlt['challengetime']) > 1000) &&
($sqlt['status'] == 'pending'))
{
$sqlt1 = mysqli_query("UPDATE challenge SET $sqlt['status'] ='inactive'");
//Also tried with if instead of while
}
with just
$sql = "UPDATE challenge SET status = 'inactive' WHERE status = 'pending' AND 1000 < UNIX_TIMESTAMP() - challengetime";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error()); //TODO better error handling
}
Now to make it execute periodically on it own you don't necessarily need php. You can:
First option Use MySQL event.
To execute this statement every day at 11pm
CREATE EVENT change_status
ON SCHEDULE EVERY 1 DAY
STARTS CURDATE() + INTERVAL 23 HOUR
DO
UPDATE challenge
SET status = 'inactive'
WHERE status = 'pending'
AND 1000 < UNIX_TIMESTAMP() - challengetime;
Use SHOW PROCESSLIST to check if event scheduler is enabled. If it's ON you should see a process "Daemon" by user "event_scheduler".
Use SET GLOBAL event_scheduler = ON;to enable the scheduler if it's currently not enabled.
More on configuring event scheduler here
Second option Use crontab to invoke CLI mysql
/usr/local/mysql/bin/mysql -uuser -ppassword -e " UPDATE challenge SET status = 'inactive' WHERE status = 'pending' AND 1000 < UNIX_TIMESTAMP() - challengetime"
If your web & PHP server is running on Linux (which is often the case) and if the delay x is more than a few minutes (i.e. x>=5 minutes) then you could use crontab(1) and add a crontab(5) entry. Remember to use absolute paths there. That entry would run (periodically) some script (which you could code in PHP, but also in some other scripting language like Python or OCaml) which would update the MySQL database.

php and mysql session destroyed before update

so im trying to have a table that shows which users are online on my site I have everything working besides the part where if someone closes the site without logging out first they stay on the table as logged in. i'll try to eplain my situation the best I can.
in my database I have a users table in that table is online when you login your online status is set to 1, when you click logout online is set to 0. here is the code im trying to use so that if someone is inactive for 10minutes they will be logged out ( online set to 0 )
<?php
session_start();
$timeout = 10; // Set timeout minutes
$logout_redirect_url = "logout.php"; // Set logout URL
$timeout = $timeout * 60; // Converts minutes to seconds
if (isset($_SESSION['last_activity'])) {
$elapsed_time = time() - $_SESSION['last_activity'];
if ($elapsed_time >= $timeout) {
mysql_query("UPDATE users SET online = 0 WHERE username = '".$_SESSION['username']."'")
or die(mysql_error());
session_destroy();
header("Location: $logout_redirect_url");
}
}
$_SESSION['last_activity'] = time();
?>
This works fine it logs them out if they wait the 10minutes, but if they just close the browser it keeps online = 1 which displays them on the list.
I believe the problem is that when they close the browser that destroys the session before it gets the chance to update the users online and set it to 0
is there anyway around this? help would be very much appreciated thanks :)
btw I know not to use mysql anymore and everything, I will try to switch to something else once I learn more and get everything working first.
The underlying problem is that when a user closes their browser, there's no reliable way to first communicate with your server. [There are things you could try, but in my opinion that's a rabbit hole you shouldn't go down] All you really "know" is how recently the user visited your site logged-in. (in your case $_SESSION['last_activity']).
At a basic level, you will want to start persisting that information in your database, and then have a process kicked off occasionally to cleanup stale sessions.
e.g.
//On page load with a logged-in user
mysql_query("UPDATE `users`
SET `last_activity` = '" . time() . "'
WHERE `username` = '" . mysql_real_escape_string($_SESSION['username']) . "'");
note that assumes you've added an INT column to your table named last_activity
and then in a process that executes, say, every 15 minutes:
mysql_query("UPDATE `users`
SET `online` = 0
WHERE `last_activity` < '" . strtotime('-30 minutes') . "'");
Unix servers have something called cron especially for period tasks/scripts, so that's what I would recommend for kicking off your cleanup script.

Categories