Update database every hour without cronjob - php

Alright, So users in my game have an hourly income. Each hour I have a cronjob run to check and see if it's time for them to be payed. It works and all, But I want to stop using cronjobs as much. Here's the coding. The coding works and I've done things without a cronjob before by using a timestamp and calculate if it's ready for the user to be able to do the function, but they have to be logged in for that. If the users not logged in for a day or so would still like them to get their hourly income each hour without cronjob.
Here's the coding:
<?php
$result = mysql_query("SELECT * FROM users ORDER BY id");
while($row = mysql_fetch_array($result)) {
$total_pay = $row['income'] - $row['upkeep'];
$timestamp_hour = time() + 3600;
$inactive_time = strtotime('+1 week',$row['last_login']);
if(time() > $inactive_time) {
$income_add = '';
echo '<div style="color: red;">'.$row['username'].' | <i>Inactive</i></div>';
}
elseif(time() < $inactive_time) {
$income_add = mysql_query("UPDATE users SET cash=(cash+".$total_pay."),energy=(energy+".$e_income.") WHERE id=".$row['id']."");
$update_time = mysql_query("UPDATE users SET payment=".$timestamp_hour." WHERE id=".$row['id']."");
echo '<div style="color: green;">'.$row['username'].' | <i>Active</i></div>';
$res = $income_add & $update_time;
}
}
?>
Would their be a way to do so without a cronjob?

Since everyone in the comments are saying the same thing - I would like to put in the same input with as much details as possible as to why you should leave it as a cron job.
1) Without a cron job or job that runs infinite with a sleep (which in essence is a cron job by itself) there is no PHP being done UNLESS you drive enough traffic that your script gets activated by a user visit (ie check if last run was more than current time, then activate)
2) the sole purpose of a cron job is to activate a set script on the clock X amount of determined time...
3) if you write your cron job effecive enough with enough fail safe you can have it small on ressources such as:
a) dont overload memory with large arrays
b) dont pull large amount of data and let it lock your table.
c) make your cron job select specific amount of data and terminates with it...if there is left over the cron job will activate itself and continue to do work until it catches up. Once caught up it will terminate quick and easy.
4) you have mentioned that people are paid at different times - the cron job shouldnt restrict that - it is up to your code and models to effectively check those time vs time now checks in order to update, so that the cron can do work when it is needed or sleep when it is not suppose to , as an example i can make a cron wake up every 5 mins but inside the code it can check current time vs last run time (via a select or last written log) and check if it should run or not. So with that you shouldn't believe that having a cron run on the clock will prevent different circumstances of your code to activate.

You can run this without a cron job on your server by using a monitoring service. Follow these steps:
Place your php script somewhere in your web path.
Open a free site monitoring account at http://www.montastic.com/
Point the site checker to the script's URL: www.YourSite.com/yourscript.php
Set the monitoring interval to 1 hour.
Enjoy!

Related

To send a message with a delay in PHP (without "sleep" function)

Trying to make a dice-roll function in my telegram bot.
How it works right now:
When a user sends "roll" bot replies with sendDice method and sends another message with result like "you rolled 5, you won and blah-blah .."
> how it looks <
The problem is — the second message should not appear instantly, ideally after dice-roll animation is finished.
My first and obvious try on that was to add "sleep(3)" before sending the second message, and it worked fine, until I realized it completely delays the execution of my script for those 3 seconds. (if two users rolled at the same time, one of the users has to wait until another guy's roll will be finished). So it's not cool
What can I use? :c
The easiest option is to add the "task" to the "queue". The queue can be a table in the database with timestamps and chat id, when and to whom to send a message. Start another process, for example, which is started by cron, and it works for one minute. During that minute, he goes to the database and checks to see if there is something that needs to be sent now.
Crontab config
Open crontab
sudo crontab -e
Add next string
* * * * * php /path/to/cron.php >> /path/to/log/file/for/debug.log 2>&1
Cron run your script every 1 minute.
Cron.php "live" 60 second
cron.php:
$now = time();
$expectedTime = $now + 60;
while (true) {
Worker::run();
if ($expectedTime < time()) {
die(0);
}
}
Where Worker::run() your method, which get records from db, check timestamp and send message
From Wikipedia:
In computing, [..] fork is an operation whereby a process creates a
copy of itself.
When your PHP script runs, you can create multiple processes that interact with each other. Those processes run concurrently and asynchronous. This way you can have one process waiting to send the message, while the rest of the script continues to run.
Instead of starting another process, you could also start another thread. The technical difference between the two is explained here:
Forking vs Threading
PHP offers Process Control Extensions for both forking and threading. You might want to check out the example in the PHP documentation for pcntl_fork().
Depending on your needs, you might want to use a framework designed to handle concurrency throughout your application. If that is the case, I would recommend amphp.

How to run a PHP script continuously?

put in simple words:
i am writing php scripts which send and receive sms,
scripts will calculate to send users campaign SMS every week based on each user registration date, for example every monday 10 AM send sms to mr. A and every friday at 7 pm sends sms to miss B..
and php scripts will take care of everything needed ..
problem : obviously a very funny way is to have someone refresh the main page of my application every some seconds or so to be able to continue to calculate and understand what and when to do jobs, or have the main page always open on my computer so javascripts and jquery will handle the rest!
My Question : how can i have my php program or scripts to be something like awake without need to someone refreshes or have open the main page? by awake i mean like it senses the next schadule and executes it and so on ..
some raw ideas to answer : perhaps i could call the main page using ajax or curl every 10 seconds .. but i don't know how to awake ajax or curl in first place ..
i see some internet posts suggest something like command line either in linux unix or windows .. but i usually access the host not the command line is it right ? or command line is something in host and i don't know it, if so please help me ..
important example : there are php wp plugins like total cache and supper cache which seem to be always on and awake of schedules without need of somebody refreshing a page ..
please give answers all in php and php families if possible, i don't know unix or those kind of programmings at all ..
------- accourding to answers made some progress to question ..
now i have this bellow script :
ignore_user_abort(true);
set_time_limit(0);
$data = file_get_contents('filename.txt');
$data = $data+1;
file_put_contents('filename.txt', $data);
$page = $_SERVER['PHP_SELF'];
$sec = "4";
header("Refresh: $sec; url=$page");
it works! even when i restart the local host . main problem is now when i closed the main page it stopped incrementing in filename.txt and when reoppend the page two instance where running the increment continued so :
should'nt it continue to increment even when i close the page ?
and how i stop it ?
and is it normal to have more than one instance of the page run in background?
finally : according to instructions on this page it's best i create a starter or reload page then use commands to initiate this reload page for example every 1 minute and then write PHPs like normal ..
last not least : how to stop this background script ? for update or maintenance ..
For this particular issue cron jobs have been invented. Cron jobs are timed jobs that can for example execute a PHP script.
You could set up a cron job to check which user should receive his/her sms every hour. Depending on your operating system you can set up these cron jobs. For linux distrubutions there are tons of guides on how to set this up.
From Wikipedia:
The software utility Cron is a time-based job scheduler in Unix-like computer operating systems. People who set up and maintain software environments use cron to schedule jobs (commands or shell scripts) to run periodically at fixed times, dates, or intervals. It typically automates system maintenance or administration—though its general-purpose nature makes it useful for things like downloading files from the Internet and downloading email at regular intervals. The origin of the name cron is from the Greek word for time, χρόνος (chronos). (Ken Thompson, author of cron, has confirmed this in a private communication with Brian Kernighan.)
I have added a resource explaining how to use cron jobs.
An alternative method is to keep a PHP script running in the background:
// Keep executing even if you close your browser
ignore_user_abort(true);
// Execute for an unlimited timespan
set_time_limit(0);
// Loop infinitely
// If you create a file called stop.txt,
// The script will stop executing
while (!file_exists('stop.txt')) {
// Retrieve user data and sens sms messages
// Wait for an hour
sleep(3600);
}
Update
ignore_user_abort(true);
set_time_limit(0);
$data = file_get_contents('filename.txt');
while (!file_exists('stop.txt')) {
// Add 1 to $data
$data = $data+1;
// Update file
file_put_contents('filename.txt', $data);
// Wait 4 seconds
sleep(4);
}
To stop executing create a file called stop.txt
Resources
About Cron jobs
You can create cron jobs in almost all servers without accessing command prompt.
Cron job can be used to initialize php scripts in cli at specified intervals lik every minute, every hour etc

PHP and MySQL: 72 hours expiration for a task

I am trying to create a site in PHP and MySQL where a person is assigned to do a task for another person. Time period allotted to complete the task is 72 hours.
If done, the other person will confirm so. If not, I want to take certain actions (like blocking his account, sending an email, assign the task to someone else etc.) What is the best way to do this?
As the count-down runs second-by-second, I guess I will have to run a script every second.
You could use a cronjob to check for the deadline and eventually send the email, block the account, etc...
Although, if you actually need a persecond precision, you might want to use a single process with an "infinite" cicle and some sleeps in between.
If your server is from *nix family, you could use cron/crontab. See examples of usage at: http://en.wikipedia.org/wiki/Cron and https://help.ubuntu.com/community/CronHowto
Very few things have to happen truely immediately. If you've waited 72 hours for something to happen, having an action occur within a matter of a few minutes will not matter so much.
If you really do want something to happen so quickly, and you will always have a long time between potential events, one thing I would suggest is not using a cronjob, but something more akin to what #muc has suggested - a script that runs regularly within a shell script that will keep it going (just doing an 'exec $0' at the end to rerun the script when it would exit).
The script (in PHP for example) that checks the database doesn't have to be running all the time either. Whenever it finds something that is due to happen in more than a few seconds time, it sleeps till the next event is due to happen. When it wakes up, it can double-check that it is still required, and then performs the relevant job.
<?php
$jobId = whatToRunNext();
if (! $jobId) {
exit;
}
$secsToNextJob = howLongToNextJob($jobId);
if ($secsToNextJob > 0) {
sleep($secsToNextJob);
if (! jobStillRequired($jobId)) {
exit;
}
}
doJob($jobId);
exit;
Wrap that in a shell sript that will keep it running, maybe with a small sleep in the bash script, and you'd be good - while not being in a very long-running, cpu-killing loop.
If I needed to do something like that, I would probably go by these steps:
Create event and calculate deadline
Set up a cronjob to run at the deadline time
cronjob checks the event status and takes actions
I think this will be the most efficient way in doing it.
I am trying to create a site in PHP and MySQL where a person is
assigned to do a task for another person. Time period allotted to
complete the task is 72 hours.
These could simply just be db vales
table_task
.id
.user_assigned
.strart_date
.end_date
.status
.desc
If done, the other person will confirm so. If not, I want to take
certain actions (like blocking his account, sending an email, assign
the task to someone else etc.) What is the best way to do this?
This again, Admin panel of some form with a layout of assigned jobs, the ''worker'' should be required to post a job as ''done'', the ''admin'' can then confirm this. This can all be managed via Values in the db ''table_task.status''
As the count-down runs second-by-second, I guess I will have to run a
script every second.
^-- server suicide
Run the cron ever hour at most. If you have 1000 users. Then this cron will run 1000 a sec
in an hour this is, 60000*60
If you need to display the time use some jQuery of some form. There are lots of clock scripts.

Schedule PHP script execution dynamically

I think Cron may be the best answer for this, but the task seems daunting and I know so little about cron, it's probably best that I ask first.
I am writing an API for an iPhone application that schedules shared tasks in a group. This will require sending push notifications at various times. Here is one example:
Person A assigns a task for Person B to complete in n days. This task is added, Person B is notified that the task has been assigned and after n-1 days a reminder notification is sent, if the task was not completed after n days, another notification is sent alerting Person B that they failed to complete the task.
My assumption here is that the process would go something like this:
When the task is initially assigned and the task is added to the DB, a cron scheduling script would be called which would schedule 2 cron jobs - 1 to fire the reminder notification, and one to fire the failure notification.
When the task is completed, it calls another script which either marks the task as completed in the DB (or removes it), and un-schedules the cron jobs.
Am I way off base here, or is this the easiest way to take this on? If it is - are there any PHP classes to make dynamically scheduling (and un-scheduling) cron jobs easier?
You could have a cron job that fires once every day.
This loops through data in the database, if a reminder needs to be sent (e.g. n-1 days is today, send the notification).
If that date has passed and it isn't complete, then it can send the failure notification.
If the task is complete, then you can change the database in that cron task, or a seperate one that fires more often.
Hopefully that helps.
My advise would be: determine what the fastest response needed would be (every minute, every 10 minutes, every hour etc.) and run a cron script in that time frame.
The script itself could be PHP, en when the script runs it figures out what to do, what actions are needed etc.
I worked on a mailing queue recently, and I implemented it as follows:
There is a one cron job that fires every minute a script, that check if database contains any e-mails in the queue. If they are found, script sends them out.
There is another cron job, that fire every day which adds scheduled e-mails to database (with a specified time, when to send it out).
So, there is a daily cron job that generates jobs to be processed at various times, and there is another one which runs constantly and processes jobs in queue.
It's easy to add some priority mechanisms too.
Your host will likely offer a cron capability in your hosting control panel. The few times I have used it, I have found that it is a case of putting in the file that you want to run's path on the server then from a couple of drop downs select the frequency. From there you are off..
As for the solution you could have AS A VERY SIMPLE EXAMPLE...
cron.php
<?php
/*
Steps
1 - Set any completed tasks to done
2 - Check if users need to be notified and send the notifications
*/
function send_notifications($email,$time_ends){
// insert code here to deal with sending the notification to the iphone
}
include("db.php"); // contains your MySQL connection vars or whatnot
// STEP 1 - Set any completed tasks to done
$update_db = mysql_query("UPDATE Notifications SET complete = '1' WHERE time_completed > '0000-00-00 00:00:00'");
// STEP 2 - Send any outstanding notifications out
$result = mysql_query("SELECT * FROM Notifications WHERE time_completed = '0000-00-00 00:00:00'"); // add another where clause to prevent bombarding with notifications for example " AND notification_2_days = '0'"
while($row = mysql_fetch_array($result))
{
send_notifications($row['email'],$row['time_ends']);
// insert an update query here to flag as a notification sent, you dont want to bombard
}
?>
WARNING - This is using depreciated connection code for simplicity (look up MySQL PDO etc) and this lacks any kind of security.
cron is great for scripts run on a regular basis, but if you want a one-off (or two-off) script to run at a particular time you would use the unix 'at' command, and you can do it directly from php using code like this:
/****
* Schedule a command using the AT command
*
* To do this you need to ensure that the www-data user is allowed to
* use the 'at' command - check this in /etc/at.deny
*
*
* EXAMPLE USAGE ::
*
* scriptat( '/usr/bin/command-to-execute', 'time-to-run');
* The time-to-run shoud be in this format: strftime("%Y%m%d%H%M", $unixtime)
*
**/
function scriptat( $cmd = null, $time = null ) {
// Both parameters are required
if (!$cmd) {
error_log("******* ScriptAt: cmd not specified");
return false;
}
if (!$time) {
error_log("******* ScriptAt: time not specified");
return false;
}
// We need to locate php (executable)
if (!file_exists("/usr/bin/php")) {
error_log("~ ScriptAt: Could not locate /usr/bin/php");
return false;
}
$fullcmd = "/usr/bin/php -f $cmd";
$r = popen("/usr/bin/at $time", "w");
if (!$r) {
error_log("~ ScriptAt: unable to open pipe for AT command");
return false;
}
fwrite($r, $fullcmd);
pclose($r);
error_log("~ ScriptAt: cmd=${cmd} time=${time}");
return true;
}

PHP: execute script 5 minutes after first script is run

I'm making a PHP site, and I would like to have a script (when you click a button) which adds some info to my MySQL database (I can do this part by myself) and it executes a script 5 minutes later. Maybe it's not difficult, but it's hard to google stuff like this.
Sleep is a VERY bad idea. Client browser would have to wait 5 minutes to finish request!!!
In my opinion it's not possible to do it like you want to.
You should create another script which queries database and checks if there is new data (and on successful fetch does the job). This script should be run by cron every N minutes.
Pretty tough one.
I'd go for something like this:
your original script adds a record to the database, containing its time of execution,
another script contains the action that needs to be taken 5 minutes later - but launches it only if the db record mentioned above contains a timestamp of at least 5 minues ago (hope that's clear enough, I'm having trouble phrasing this)
set crontab to execute the second script every X minutes (perhaps 2).
It won't be 5 minutes EXACTLY, but rather something between 5 and 7 (in case you choose to launch the script every 2 minutes). Would that do?
You could implement a queue in your database, where you add "commands" to be executed, and also store when to execute this command. Then have a cron job that runs every minute and checks said queue to see if it's time to execute a certain command.
If you're on a unix box:
exec("echo 'php script.php' | at now +5 minutes");
Which will schedule the php script.php command to run after 5 minutes.
I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes.
Considering this is your actual goal, I recommend just saving the original building with a timestamp.
I know you tagged your question with PHP, but I don't want to include all the overhead of handling mysql queries in PHP, especially since I don't know how you prefer to execute the queries or what framework you're suing, so here's some pseudocode to handle this "building buildings" task:
build.php
building_type_id = sanitize(POST['id'])
user_id = current_user['id']
query('INSERT INTO buildings (user_id, building_type_id, created_at)
VALUES (' + user_id + ', ' + building_type_id + ', CURRENT_TIME)');
my_buildings.php
user_id = current_user['id']
completed_buildings = query('SELECT * FROM buildings b
LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) < NOW();')
under_construction = query('SELECT * FROM buildings b
LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) > NOW();')
Hope this helps!
IMHO the best way is: On button click save the job to run in the db with the time it should run. Write a small daemon, fetches every 10/5/2 seconds new jobs which should be executed and executes them.
EDIT: Btw the idea using cron for checking for new jobs to execute, is better, but only if you have a small website and you don't need to do load balancing for the jobs.
The way I would do this is to run a cron job between the two scripts.
the first script sets a value in a database table.
the cron job executes the second script. every minute or what not.
the second script checks for the database value set by script 1 to decide whether to run entirely or not.
I would suggest doing the timer in Javascript rather than PHP.
Put a timestamp in the user's $_SESSION to indicate when they started the event, and then have Javascript call back to the browser after five minutes.
PHP would still need to know the start time (to prevent the user from hacking the game by tweaking the Javascript time-out), but it wouldn't need to actually do any count-down timing or sleeping or anything like that itself.
You could fork the process and in the child fork, do a sleep for 5 minutes before executing your second script. I've tested this and it appears the child process will still execute even after the parent has finished. Something like
//initial code
$pid = pcntl_fork(); //fork the process
if ($pid==0) // if in the child
{
exec("sleep 300; php second_process.php"); //sleep for 5 minutes and execute second script
return; // or exit
}
// rest of initial script...
The "return;" is important as the rest of the script will execute a 2nd time (i.e. in the child) unless it's there.
Someone asked about the purpose of this and your answer was:
"I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes"
You don't actually need to time an execution for this. You can do it all in one run by storing buildStartedAt and buildFinishedAt as part of the building-schema.
Now maybe you want the building to have a nice animation when it finishes, then you just do all of that on the frontend but make sure nothing meaningful can be done with the building if the timestamp is before the buildFinishedAt time in order to a void cheating by potential hackers.
Are you looking for that?
sleep php.net

Categories