I am trying to figure out how to do time scripting in PHP. Basically let's say in my application, I want to do a task at timed intervals (e.g., send email notification to users everyday, do some database cleanup at certain times, etc.) How is this type of scripting (scheduling) is done in PHP? If not possible in PHP, then how to do it and in what language? I am both Linux and Windows sharing hosting accounts, so I would like this method if possible to be universal.
Any help is appreciated.
I just schedule cron jobs that run PHP scripts.
*/5 * * * * php /var/www/cron/cleanup-db.php
An alternate (Windows-compatible) approach would be to run a persistent PHP script which sleeps for an interval, and on wakeup it checks to see if any jobs need to be run. For example, check to see if any pending requests have not had a response or a reminder email in N hours.
On Unix machines, you use cron, which is for re-occuring jobs. On Windows, the equivalent is at
Cron is the obvious choice but you may not be able to use it because you host your site on a "shared" environment. Try online services that generate auto http requests to your URLs based on the schedule you set. Google "schedule http request online", there are many of such services out there, some of them are free or have free options.
To complete Adam's answer, in Windows you have the chance to make Scheduled Tasks, wich can be programed to given intervals. That's the way we do.
The problem I see is that you are talking about shared hostings, probably you don't have rights to schedule task in that environment. In that case you should ask your system admin if such task is available.
There is another requirement: the task can be made in php if you have php-cli available, so check it out too.
You are looking for cron job
http://en.wikipedia.org/wiki/Cron
Related
Is it possible to schedule a task with PHP? like, I want to choose a date with the jQuery datepicker, and submit it. When that date equals today's date, an email will be sent for example (or any other PHP script). The date will be different depending on the user, also, every user can have a number of scheduled tasks to run.
EDIT
The OS is Linux, and the website is hosted on godaddy.com
Also, it's the end users who will choose when to run these tasks, so they can use command lines for that.
EDIT
Any Ruby on Rails or Django solutions are welcomed as well.
If you're using a Unix server, try at.
http://www.manpagez.com/man/1/at/
It works in a similar way to cron, in that it's totally separate from PHP, and you need to shell_exec() an external command. However, it has a simple command-line interface. Like cron jobs, at jobs survive reboots.
If you use at you'll have to write a separate script to perform the task you want scheduled.
Example:
shell_exec("echo 'php script.php' | at -t 201208011234.56");
Will run script.php on August 1st, 2012 at 12:34:56.
You need some process in the server side to run the task at the scheduled time.
A popular approach is to store the task information in some database and have a cron job checking the task queue from time to time - it is very reliable and safe.
It is impossible to give a better answer without more information about the environment where it will be deployed. For example:
target OS
hosting type (dedicated, shared, cloud)
do you have administrator privileges?
is it exposed to the internet?
Most likely you will not be able to do that in a shared hosting environment, anyway, but I must say that having a website calling shell_exec is not very wise from a security standpoint, so I would avoid that if the site is exposed to the Internet.
A good hosting provider should have some kind of background task scheduler available, even if it is not crontab. If your hosting provider hasn't, trying to pull some stunt to fill the gap probably is a bad idea.
[update]
As I said in the edited part of the original post, I'm hosting it on godaddy.com, and I can't let the clients run these command lines etc. Is there a solution with other languages too?
I'm not hosting at godaddy anymore but they used to have a "Cron Manager" at their control panel. I think the correct goDaddy cron setup is
/usr/bin/wget -O - -q "http://yoursite.com/cron.php" > /dev/null 2>&1
at the Command Option in the Cron Manager. This "cron.php" will check the task queue to see if there are any email to send (the task queue being a simple table in your database where you will record any task scheduled by your customers).
You can do this without cron by simply adding a check into the main index page, or a standard include file - but that's only for when you really can't get access to cron (e.g. shared hosting). In this check you'd grab the list of outstanding actions and execute them, possibly by using
if (time_since_last_run > 5*60) // minutes
shell_exec("/usr/bin/php /var/www/check-tasks.php &");
The best solution is to use cron to launch a PHP script that will check for scheduled items within your system and execute them. You can either do this via wget or directly via calling PHP.
One shared hosting site that I have is externally scheduled from another of my servers via cron and wget http://othersite.example.com.
example crontab entry:
0 * * * * wget -O - -q -t 1 http://othersite.example.com/cron.php
right now, we have a single server with a cronjob tab that sends out daily emails. We would like to scale that server. The application is standard zend framework application deployed on centos server in amazon cloud.
We already took care of the load balancing, content management and managing deployment. However, the cronjob is still an issue for us, as we need to grantee that some jobs are performed only once.
For example, the daily emails cronjob must only be executed once by a single server. I'm looking for the best method to grantee only one server will execute it only once.
I'm thinking about 2 solutions, but i was wondering if someone else had the same issue.
Make one of the servers "master", who only sends out the daily emails. That will be an issue, if the server malfunction, and generally we don't want to have a "special" server. It would also means we will need to keep track which server is master.
Have a queue of schedule tasks to be performed. Each server open that queue and sees which tasks needed to be performed. The first server who "grab" the task, will preform the task and mark it as done. I was looking at amazon simple queuing service as a solution for the queue.
Both these solutions have advantages and disadvantages, and i was wondering if someone thought about someone else that might help us here.
When you need to scale out cron jobs, you are better off using a job manager like Gearman
Beanstalkd could also be an option for you.
I had the same problem. What I did was dead simple.
I spun up the cheapest EC2 instance on AWS.
I created the cronjob(s) only on this server.
The cron job just run jobs that only makes a simple request to my endpoint / api (i.e. api.mydomain.com).
On my api, i just have a route watching for these special request that will run the job I want. So basically, all I'm doing instead of running the task using a cronjob, im running the task via a http request.
I hope that makes sense! Now it doesn't matter how many servers you have, it will just scale! Also, your cronjob server's only function is to run dead simple jobs to send a request, nothing more.
I run a website and my subscriber base is gradually increasing.
I had to manually batch my subscribers, that is Batch A (1-700), Batch B (701 - 1400) etc. and manually trigger the email sending every hour.
In addition, to sending them emails i want to perform some other tasks along side the email.
I believe there should be a way of triggering the message send once from the web interface (that is from my website backend, pls not from the command line), and it batches the emails and processes automatically hourly.
Looking forward to replies on how i can get it done.
Thanks in advance.
If you are unable to schedule cron jobs on your server (as is the case with most cheap hosting solutions), there are some pure php alternatives to run scheduled jobs: phpjobscheduler is one of those alternatives.
In UNIX-like systems, this can be done with cron. In Windows, see the Task Scheduler, schtasks or at.
If you don't have access to these tools, you cannot programatically run scripts with a given period (short of having another machine call your scripts via HTTP).
I am creating a web application using zend, here I create an interface from where user-A can send email to more than one user(s) & it works excellent but it slow the execution time because of which user-A wait too much for the "acknowledged response" ( which will show after the emails have sent. )
In Java there are "Threads" by which we can perform that task (send emails) & it does not slow the rest application.
Is there any technique in PHP/Zend just like in Java by which we can divide our tasks which could take much time eg: sending emails.
EDIT (thanks #Efazati, there seems to be new development in this direction)
http://php.net/manual/en/book.pthreads.php
Caution: (from here on the bottom):
pthreads was, and is, an experiment with pretty good results. Any of its limitations or features may change at any time; [...]
/EDIT
No threads in PHP!
The workaround is to store jobs in a queue (say rows in a table with the emails) and have a cronjob call your php script at a given interval (say 2 minutes) and poll for jobs. When jobs present fetch a few (depending on your php's install timeout) and send emails.
The main idea to defer execution:
main script adds jobs in the queue
cron script sends them in tiny slices
Gotchas:
make sure u don't send an email without deleting from queue (worst case would be if a user rescieves some spam at 2 mins interval ...)
make sure you don't delete a job without executing it first ...
handle bouncing email using a score algorithm
You could look into using multiple processes, such as with fork. The communication between them wouldn't be as simple as with threads (but then, it won't come with all of its pitfalls either), but if you're just sending emails, it might not be necessary to communicate much, if at all.
Watch out for doing forks on an Apache process. You may get some behaviors that you are not expecting. If you are looking to do any kind of asynchronous execution it should be via some kind of queuing mechanism. Gearman is one. Zend Server Job Queue is another. I have some demo code at Do you queue? Introduction to the Zend Server Job Queue. Cron can be used, but you'll have the problem of depending on your cron scheduler to run tasks whereas asynchronous computing often needs to be run immediately. Using a queuing system allows you to do that without threading.
There is a Threading extension being developed based on PThreads that looks promising at https://github.com/krakjoe/pthreads
There is pcntl, which allows you to create sub-processes, but php doesn't work very well for this kind of architecture. You're probably better off creating a long-running script (a daemon) and spawning multiple of them.
As of PHP there are no threads in it. However for php, you can have a look at this roundabout way
http://www.alternateinterior.com/2007/05/multi-threading-strategies-in-php.html
You may want to use a queue system for your email sending and send the email from another system which supports threads. PHP is just a tool and you should the tool that is best fitted for the job.
PHP doesn't include threading as part of the language, there are some methods that can emulate it but they aren't foolproof.
This Google search shows a few potential workarounds
I want to a e-cards or something like that. The user can choose the e-cards, after chosen, he must enter the some fields like name(to and from), email(to and from), message and I want to let user to choose which date to send the e-cards.
How to send the e-cards on specific day? I need to write a script that run every new day? How to do that? Sorry, I am new to php... (but not beginner like not even know how to execute mysql query, get message from url etc)
Yes, you need a script that runs every day. (Barring ridiculous maneuvers like trying to fake this by checking on Web requests.) The usual way to do this in a Unix context is called a cron job; if your hosting provider is Unix-based, you should look into what they provide for making cron jobs available to you. On Windows there's a parallel service called Scheduled Tasks.
A similar question was disscussed here resetting-a-mysql-field-value-without-user-execution
I'll just reiterate: There are web based cron services too. This could come in handy if you only got a shared hosting plan and can't add cron jobs. They will call an URL at a regular interval that you can set. Usually very cheap. (Cheaper than upgrading to a root-access server anyway.)
Just search Google for web based cron
ciao!
/0
This is for *nix.
Let's say you have a php script that sends email on a specific day called mailer.php
<?php
//mailer.php
if (date("m/d/Y") == "06/02/2009") {
mail("client#email", "Subject", "Body");
}
?>
We are going to assume that you already have cron daemon running in the background.
If you have root access to your machine, then setting up a cron job is simple as editing a file.
Open up /etc/crontab file and add the following task:
1 14 * * * root php /path/to/your/scrip/mailer.php
This means, as a root, the mailer.php script will be running daily at 02:01PM. You can change the numbers to whatever you desire.
This is somehow complex. First it depends on your system. If it is Linux/BSD/Unix/Solaris then you have this handy utility as cron. If you are using Windows, you have Scheduled Tasks. Run your script daily (or as you wish) and check what cards you have to send today.