Recurring event in PHP - php

Hi there I'd like to make a recurring event based on calendar basis. The thing I want to ask is this: How to trigger the event? If the client doesn't login or open the webapp to trigger the event in the constructor, how do I make the code to run anyways.
I know cron jobs maybe the solution, but is there any other solution?(I want to avoid cron jobs).

You have to have something running in order for this to work; a cron is ideal for this, as it can run a script at regular intervals to check for things like events.
Without that, you are left by this being triggered by user action, but like you said, that user might not always log in to trigger it.
You could modify your code to have any user trigger actions for all users. It's a little more complex, as you'd need to allow for multiple users logging in at the same time when you only want one of them to trigger stuff. I would set up a table in your database to keep track of the last time things were triggered, and then if the gap since then and now is large enough when a user logs in, add a new entry in the table with the time now to prevent another user triggering this, and trigger the bits you need to run.
Like I said though, this won't be a perfect solution, and I really would recommend using cron. Is there any reason why you want to avoid using cron?

If that job should be triggered to keep the server in a good state, it should be run using a cron job, if its a database management, the database manager have the event's table to make cron jobs, if it's needed for only for the user, it can be a workload safe if you just don't do it until user login. You can manually login to trigger the event too, to an admin page maybe.

Related

Wordpress cron wp_schedule_single_event – action not always working

I'm registering an event like:
wp_schedule_single_event( time(), 'do_custom_hook', array( $body ) );
Above that, I have added the following action:
add_action('do_custom_hook', 'process_custom_hook', 10);
function process_custom_hook($body){
// custom code here
}
However, sometimes the process_custom_hook function fires, while other times, it simply doesn't (it fires most times, though. It's missed about 10%-20% of the time)
The event is always returning true, meaning that it must have registered.
Also, while testing, I made sure that the arguments (body) is always different.
Any reason why this may occur?
From the codex:
Note that scheduling an event to occur before 10 minutes after an existing event of the same name will be ignored, unless you pass unique values for $args to each scheduled event.
If your custom hook is only working some of the time, then this might be an avenue to look at. If you require the hook to be handled immediately, then it might be prudent to look at giving a hook a unique name, or passing unique values to the hook.
If you do not need your job to execute immediately, then you could look at utilising wp_next_scheduled() to determine when the job will next run, and set a job to run after the next scheduled job.
It's also worth noting that if this task is something which seems to have consistent logic behind it (as seems to be the case) - why not store the job information in to the database and run a cron job every 5-10 minutes to pick up any new jobs from the database and handle them as such? This would avoid needing to deal with the behaviour of wp_schedule_single_event().
According to the official documentation on this instance,
Scheduling an event to occur within 10 minutes of an existing event with the same action hook will be ignored unless you pass unique $args values for each scheduled event. which you have stated tht you did but maybe a double check will help.
It is dependent on when a user visits the site so the action will trigger when someone visits your WordPress site if the scheduled time has passed.
Documentation also says you could use wp_next_scheduled() to prevent duplicate events and use wp_schedule_event() to schedule a recurring event.
The schedule might return true in certain instances where it run but was ignored. so it did run but it was ignored.
I would suggest a detailed log of everything that is sent and received so you can see for yourself if what is occuring is same as what you are confident on.
here are a few links with similar issues and documentation you could look at.
I hope this helps. if not, lets figure it out together.
https://developer.wordpress.org/reference/functions/wp_schedule_single_event/
https://wordpress.stackexchange.com/questions/15475/using-wp-schedule-single-event-with-arguments-to-send-email
https://rudrastyh.com/wordpress/wp_schedule_single_event.html
http://hookr.io/functions/wp_schedule_single_event/
From Wordpress Document:
WP-Cron works by checking, on every page load, a list of scheduled
tasks to see what needs to be run. Any tasks due to run will be called
during that page load.
WP-Cron does not run constantly as the system cron does; it is only
triggered on page load.
Scheduling errors could occur if you schedule
a task for 2:00PM and no page loads occur until 5:00PM.
I think your cron event may be missed because there is no page loads occur the scheduled time.
Here is a solution for your problem:
Hooking WP-Cron Into the System Task Scheduler
As previously mentioned, WP-Cron does not run continuously, which can
be an issue if there are critical tasks that must run on time. There
is an easy solution for this. Simply set up your system’s task
scheduler to run on the intervals you desire (or at the specific time
needed). The easiest solution is to use a tool to make a web request
to the wp-cron.php file...
In my case this exact issue occurred when also Woocommerce's action scheduler was running. Action Scheduler is a cron task manager that ships with Woocommerce, but also other plugins like for instance wp-mail-smtp.
I had exactly the same issue and couldn't figure out what was wrong. I've tried to debug the Wordpress code, and came to the conclusion that when a task was scheduled (meaning, the moment it was added to the scheduled tasks) within 10 second of each whole minute, it just got removed straight away. It seemed some sort of racing condition where the action scheduler just popped it of the stack without the normal wp cron being able to execute it, because the task was already gone.
I need to also say, that I've setup crontab calling wp-cron.php every minute on the minute (instead of the 'fake cron' of Wordpress).
When I replaced wp_schedule_single_event with the as_enqueue_async_action function of the Action Scheduler, no tasks were dropped anymore.
I think an alternative is deinstalling anything that uses Action Scheduler, but I haven't tried that.
You are using cron from Wordpress but some plugins disable or prevent CRON from working. My recommendation in this case is either you create this schedule through the Server Cron or you install a plugin to reaffirm your schedule.
I had the same problem it was even a little difficult to find ... And as you will see it doesn't have a current update, but for me it works. https://wordpress.org/plugins/wp-crontrol
&
https://br.wordpress.org/plugins/advanced-cron-manager/
you can identify which Cron you want to edit and thus have more precision in your edition. There are other plugins that can and should be related to this one. you mentioned about cron's schedule. That's why I indicated this one. So, you can know the Chrome configuration on the calendar. WP Cron you can edit your Cron schedule

How to take an action after certain time (different from user to user)?

I'm developing a web game (js php mysql) in which one clicks a button to start an action that takes time to complete (let's say 10 hours) and when it finishes some points are added to that player's total.. The problem is that I need those points to be added even if the player is not online at the time the action finishes.. for example I need to have the rankings updated, or an email sent to the player..
I thought about a cron job checking constantly for ending actions, but I think that would kill the resources (contantly checking against actions of thousands of players..).
Is there a better solution to this problem?
Thanks for your attention!!
You can just write into your database when it's finished and when the user logs in you add the earned points to his account. You can also check with a cronjob. Even if you have millions of user this will not kill your server.
Cron is perfect for this. You could write your tasks in stored procedures, then have cron run an SQL script to call the stored procedure that would update the records of your players.
Databases are designed to work with thousands and millions of pieces of information efficiently, so I don't think the idea that it will kill system resources is a valid one unless you hosting system is really constrained already.
If you want to be safe against cheating you need to do the checking on the server anyway. If the "waiting" will happen within a Javascript on the client, one could easily decrease the remaing time.
So you need to send the job to the server (which is assumed to be safe against clock modifications) and the server will determine the end timestamp. You could store your jobs in a queue.
If you only need this information for the user himself you can just look at the queue when the user logs in. Otherwise run a cron job every minute (or so). This job will mark all jobs finished when their timestamp is in the past (and remove them from the database).
If you need more precise checking you will need to come up with an alternative server side solution that is doing this more often (e.g. a simple program polling the database every few seconds).

Can php launch scripts without user interaction in order to interact with the database?

I've search on the web and apparently there is no way to launch a php script without user interaction.
Few advisors recommend me Cron but I am not sure this is the right way to go.
I am building a website where auctions are possible just like ebay. And after an amount of time the objects are not available anymore and the auction is considered as finished.
I would like to know a way to interact with the database automatically.
When do you need to know if an object is available? -> Only if someone asks.
And then you have the user interaction you are searching for.
It's something different if you want to, let's say, send an email to the winner of an auction. In this case you'd need some timer set to the ending time of the auction. The easiest way to do this would be a cron job...
There are several ways to do this. Cron is a valid one of them and the one I would recommend if its available.
Another is to check before handling each request related to an object whether it is still valid. If it is not, you can delete it from the database on-the-fly (or do whatever you need to) and display a different page.
Also you could store the time at which your time-based script was run last in the database and compare that time with the current time. If the delay is large enough, you can run your time based code. However, this is prone to race conditions if multiple users hit the page at the same time, so the script may run multiple times (maybe this can be avoided using locks or anything though).
To edit cronjobs from the shell: crontab -e
A job to run every 10 minutes: */10 * * * * curl "http://example.com/finished.php"
TheGeekStuff.com cron Examples
Use heartbeat/bot implement
ation
Cron job that runs pretty frequently or a program that starts on boot and runs continuously (maybe sleeping periodically) is the way to go. With a cron job you'll need to make sure that you don't have two running at any given time or write it such that it doesn't matter if you have more than one working at any given time. With "resident" program you'll need to figure out how to handle the case when it crashes unexpectedly.
I wouldn't rely on this mechanism to actually close the auction, though. That should be handled in your database/web site. That is, the auction has a close time and either the database constraints or your code makes it impossible to bid on a closed auction. Notifying the winner and seller, setting up the payment process, etc. are things your service/scheduled task could do.

The best way to schedule a event

is there any other option other than cron to schedule the running of a php backup script at a certain time?. I know you can use php itself to schedule things, but it will only fire if the site is getting traffic.
Are there any other options ?.
Thanks :-)
If you're talking about a database backup, then MySQL 5.1 and above has CREATE EVENT which can be used to trigger events (such as stored procedures that can dump table structure/data to file) at regular intervals or set times
Well, cron jobs is a solution. But not necessary in most cases.
If your script is doing something off the site (like sending an email or something), it must be a cron-job.
But...
I made a textbased rpg-game once where several actions were stored in the database waiting to get triggered at a specified time. I found out that it did not make any difference if the script fired at the time it should, or when the first person visiting the page after the time is beyond the timestamp. You could do these events before displaying the content of the page. (I used a file called monitor, to keep it simple).
Would you like to say more about your "event"?
Unless you feel like writing a daemon/service/etc., cron would be your best bet. If you need a job ran more often than minutely, use a lockfile solution and a looping script.
Well not really, Crons are your best bet.
Other than that call a script, and if certain parameters are met such as time elapsed then run the script.

how to set cron through php script?

i have 10 users. and i want to set a cron for that 10 users. Now when a perticular user logged in he can set the corn time from his panel and cron will run at that time .Also when new user added a new cron will be set for that user with default time according to application.
how can i achieve this?
I agree with thomasmalt that it is not wise but what you should do instead is have it so your users can set a cron time in a 'users' database table (like mysql) with columns: 'interval (INT)' and 'last_update (DATETIME)'. So every user has their own time set. Then you decide what is the lowest increment you will allow (such as 1 minute) and only let your users set times higher than that.
Then you run a cron every 1 minute which checks the 'users' table. Find any users where interval is less than or equal to the time since 'last_update'. Then run your actions for those users. This effectively does the same thing as setting crons for every user.
This sounds generally like a very unwise thing to do, but if you know what you're doing and understand the security problems involved etc. I would suggest solving this using two scripts
one php part which lets the user view his crontab and manipulate time settings using an html form and storing the wanted changes in a known place on your system.
one shell script part running as a trusted user on your system picking up the changes at a given interval (once a minute maybe) and doing the actual updates to cron.
Adding stuff to cron is potentially a very dangerous thing and only very trusted users should be allowed to do so. Any web solution should be regarded as insecure and you should take extra care to make sure any input is properly audited.
As thomasmalt said this is probably not wise to do in a public system ... you don't want to let users mess with system crons.
I suggest you let the users specify a time of day in their controlpanel and have a cron script run every minute. In that script it's easy enough to fetch the users that match the current time and execute their script. It achieves the same thing, is a little more verbose and more to code but alot more secure.

Categories