Reading crontab-like syntax from a database to execute functions - php

I have a database of scheduled tasks that'll be run based on the normal crontab-like syntax eg. min hour dom month dow (in separate table fields).
I'm not all that good at explaining myself, however what I would like to do is just set up one actual system crontab every minute, then that PHP file will then parse my database to look for all the scheduled tasks with crontab syntax, then when it hits the right time/day/etc, execute a function..... So, for example, if I set */10 for the minutes, then * for the rest, the function should be executed every 10 minutes, checked from the every minute running system cron.
To be honest, I am not sure how I go about actually parsing the database crontab-like syntax via PHP - like, take the example I just give, every 10 minutes. I know I'd need to record the last timestamp of the said task was run and the next timestamp it will be run - however, it's just initially working out when this next timestamp will be based on the crontab syntax I'll have issues with.
Hope I have explained this clearly, and thanks in advance.

Related

PHP automatically do something 48 hours before a certain date

I'm using Phalcon 3.4 with PHP 7.2 and MySQL 4.7.3.
So in my Database I store dates (start_date and end_date) and I need to do something (send a mail to a customer) 48 hours before the start_date. I need to do that just once.
I think the only way to do that is to use cron job ?
I see only one solution for that . My solution is to create a cron job who call my web service every hour and inside my web service I gonna check if there is 1 or more start_date < to 48 hours compared from now. Then I get all related customers and I send an email for each customer.
I'm posting a question here because I'm not sure if it's very good to create an hourly cron job for that. I'd like to know if you know other solutions to do that. Maybe there is another technology ?
That's a perfect fit for cron indeed.
Possible pitfalls:
if the task takes longer than the interval (i.e. runs over 1 hr in your case), cron will happily run another one; if the processing gets long, you might want to check for that
cron won't run a missed task (e.g. if your task is scheduled at 2:30 and a DST change happens, it will skip and only run the next one) - that is already handled in your case by the "less than" check.
you may wish to set some sort of flag "this is currently processed" and then "this was processed successfully", so that e.g. a manual invocation doesn't process the same task while a cron is running
cron doesn't check that the task finished successfully, you may wish to check this directly in your main code, or run another "cleanup" cron service periodically
note also the timezones, where applicable (e.g. if all your date operations run in UTC, this is mostly a non-issue)

Uptime Monitor PHP

I am trying to create a system to monitor a Minecraft server using PHP. It will then periodically(every 10 minutes) check the status of the server. If the server is unreachable, it will time for how long it went down and then store that in a database.
I have created the code to check the server status but am struggling with timing for how long the server went off. What ways could I time the downtime ?
You cant calculate the downtime, I suggest that when a downtime is occured, you check it again in every one minute until the uptime, and get the difference of first down time and next uptime, this gives you a downtime with accuracy of one minute
you can update to the database the last up-time and calculate downtime with it and overwrite the downtime every time you calculate it
For this type of tasks, crontab is a great tool: it's a file that will execute defined commands at the time you set them.
you can use your isp's cpanel tool named cron jobs. from there it's pretty easy to create a cron job. just enter the command portion of the three lines below.
if you can't use this tool or prefer to write directly into your crontab, those lines are the resultant command (from http://www.pantz.org/software/cron/croninfo.html):
# Minute Hour Day of Month Month Day of Week Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0,10,20,30,40,50 * * * * php /home/yourdomain/public_html/test.php
my test.php:
mail('mail#internets.com','time();',date('H:i:s',time()));
this mails the time each ten minutes. from there on you patch your status checker code in test.php (or whatever name you want) and insert this data in database. I don't have enough information to provide code to calculate time. What is your data structure? How do you interact with your database?

Running a PHP script or function at an exact point in the future

I'm currently working on a browser game with a PHP backend that needs to perform certain checks at specific, changing points in the future. Cron jobs don't really cut it for me as I need precision at the level of seconds. Here's some background information:
The game is multiplayer and turn-based
On creation of a game room the game creator can specify the maximum amount of time taken per action (30 seconds - 24 hours)
Once a player performs an action, they should only have the specified amount of time to perform the next, or the turn goes to the player next in line.
For obvious reasons I can't just keep track of time through Javascript, as this would be far too easy to manipulate. I also can't schedule a cron job every minute as it may be up to 30 seconds late.
What would be the most efficient way to tackle this problem? I can't imagine querying a database every second would be very server-friendly, but it is the direction I am currently leaning towards[1].
Any help or feedback would be much appreciated!
[1]:
A user makes a move
A PHP function is called that sets 'switchTurnTime' in the MySQL table's game row to 'TIMESTAMP'
A PHP script that is always running in the background queries the table for any games where the 'switchTurnTime' has passed, switches the turn and resets the time.
You can always use a queue or daemon. This only works if you have shell access to the server.
https://stackoverflow.com/a/858924/890975
Every time you need an action to occur at a specific time, add it to a queue with a delay. I've used beanstalkd with varying levels of success.
You have lots of options this way. Here's two examples with 6 second intervals:
Use a cron job every minute to add 10 jobs, each with a delay of 6 seconds
Write a simple PHP script that runs in the background (daemon) to adds an a new job to the queue every 6 seconds
I'm going with the following approach for now, since it seems to be the easiest to implement and test, as well as deploy on different kinds of servers/ hosting, while still acting reliably.
Set up a cron job to run a PHP script every minute.
Within that script, first do a query to find candidates that will have their endtime within this minute.
Start a while-loop, that runs until 59 seconds have passed.
Inside this loop, check the remianing time for each candidate.
If teh time limit has passed, do another query on that specific candidate to ensure the endtime hasn't changed.
If it has, re-add it to the candidates queue as nescessary. If not, act accordingly (in my case: switch the turn to the next player).
Hope this will help somebody in the future, cheers!

How to delete mysql row after time passes?

I have no idea where to start with this one:
I have a database that stores postID and Date.
What I want to do is have my website auto delete all rows where Date is less than today. This script can't have any user input at all. No button clicks, nothing. The script must run every day at midnight.
I've been looking all over the place for something that does this and I've found absolutely nothing.
You can use PHP script and use cron job on your cpanel.
Example:
cronjobcommand.php
<?php
include 'your_db_connection';
mysql_query("DELETE FROM your_table_name WHERE Date < NOW()");
?>
I have attached a screenshot below for your more reference.
For those out there who are on a shared hosting, like 1and1's, and can't use cron, here are 2 alternatives :
mysql events enable you to place a time trigger on mysql, which will execute when you'll want, without having to be fired by any kind of user input
if you cannot create mysql events because you're on 1and1 :(, an alternative is to use webcron
You just need to tell webcron the url of the php script you'd like to be run, and they'll trigger it for you at the intervals you want
Why using cronjobs everyday?? Why not filter data on output. For example in your select check if post date equals today with adding a simple where:
SELECT * FROM `posts`
WHERE (DATE(`post_date`) = DATE(NOW()));
This way you're not required to do your database managements/cronjobs on any special time and it will be used just for database managements. Afterwards you can delete unnecessary data at any time using by mysql command like:
DELETE FROM `posts` WHERE (
DATE(`post_date`) < DATE(NOW())
)
Most hosts provide a cron(8) service that can execute commands at specific times. You use the crontab(1) program to manage the crontab(5) file the describes when to run which commands.
There's a lot of functionality available to you, but if you write a program (shell script, php script, C program, whatever) that runs the appropriate MySQL commands, you can call the program via cron(8) in an entirely hands-off fashion.
Run crontab -e to edit your current crontab(5) file. If none exists, hopefully you'll get one with a helpful header. If not, copy this:
# m h dom mon dow command
The columns indicate the minute, hour, day of month, month, and day of week to execute commands. All the numbers in the columns are essentially ANDed together to decide when to run commands.
Thus, midnight every night would look like this:
0 0 * * * /path/to/executable
It's remarkably flexible, so put some time into the documentation, and you'll find many uses for it.
You should set cron job (scheduled tack.) for it.
A cron job is an automated program setup for Linux and Unix operating systems. It allows the user to execute several commands or functions at a specific time and date.
you have cron Job in your cpanel setup. first you need to make a php script with your logic for delete record after each date. take date from server and write script for delete.
then go to cron tab in your cpanel and do settings for time interval to run cron and give path of your php script file.
MySQL doesn't have a task scheduler. So you have to use the task scheduler of your Operating System (CRON under Linux), or to lunch a basic task checker sub-script during the script of the main page (on another page that is supposed to display the changing data).

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