I don't have a server, so i don't have crontab access. I am thinking of using a PHP script to check current time and how much time has passed. For example, I run the script, it stores the current date in MySQL and check if 30 days have passed. If so, do my stuff.
Is it possible to do all these without MySQL? And of course it is only my thinking, i haven't tried yet.
Keeping script running:
The issue is that you've either got to keep that script running for a long, long time (which PHP doesn't like) or you'll have to manually run that script every day or whatever.
One thing you could do is write a script to run on your local machine that accesses that PHP script (e.g. using the commandline tool 'wget') every minute or hour or whatever.
If you want to have a long-running script, you'll need to use: http://php.net/manual/en/function.set-time-limit.php. That'll let you execute a script for much longer.
As noted in another answer, there are also services like this: https://stackoverflow.com/questions/163476/free-alternative-to-webcron
Need for MySQL?
As for whether you need MySQL - definitely not, though it isn't a bad option if you have it available. You can use a file if required (http://php.net/manual/en/function.fopen.php) or even SQLite (http://php.net/manual/en/book.sqlite.php) which is a file-based SQL database.
As i understand, you can only run php scripts, which involved by user request.
I tried this once, but it is dangerous. If the scheduled process took too long time, user may be interrupting it, and hanging up the script, causing half-processed data. I'm not suggesting it for production environment.
Take a look at Drupals Poormanscron module: http://drupal.org/project/poormanscron. From the introduction text:
The module inserts a small amount of JavaScript on each page of your
site that when a certain amount of time has passed since the last cron
run, calls an AJAX request to run the cron tasks.
You can implement something like this yourself, possibly using their code as a starting point. However, this implementation depends on regular visits to the pages of your website. If nobody visits your website, the cronjobs do not get executed.
You'd need some kind of persistent storage, but a simple file should do the trick. Give it a go and see how you get on. :) Come back for help if you get stuck. Here are some pointers to get you started:
http://php.net/manual/en/function.file-get-contents.php
http://nz.php.net/manual/en/function.file-put-contents.php
You could use a webcron (basically a cronjob on another server that calls your script on a given time)
https://stackoverflow.com/questions/163476/free-alternative-to-webcron
Related
I have a cron job running that executes a PHP file which checks a MySQL database for a change. I have this script running every minute but it's very simply query.
Still, is running a cron job like this every minute going to be too hard on the server? Is there a better approach to what I'm doing?
Depending on the query, if it's SQL related only, consider a MySQL event. But it depends on what it does. If PHP code is required to interact with it... events won't help. If it just does some updates in MySQL (like expired user sessions and removing unconfirmed user accounts)... an event will do.
Running every minute is not hard on the server, it depends on what it does. microtime() execution of the script and log it to a text file with register_shutdown_function() (you can also memory_get_peak_usage()). See how long it takes, how much memory it consumes... that will tell you how hard it is on the server.
A simple query like that shouldn't be an issue... most PHP pages make many more calls, and the server can be processing many requests at once. Unless it's a beast of a query, you'll be fine.
I have a site where auctions end a varying times. I need to send an automated email to the seller and the buyer after the auction is finished to notify them of the auction ending and the results. Obviously I can't really wait for someone to load the page to run the script so is there a good way to automate this by checking the current time and comparing that to the time of the auction end and running that script?
The site is on a UNIX server so a cron job is an option, but I'm concerned that running a cron job like that will put quite a load on the server.
A cron job runs at most once per minute.
Whatever load it generates on the server really depends on the kind of script you're going to run. Btw, I'm assuming that you're using cli to run the script (rather than just doing a curl http://mysite.com.
If your script takes longer than one minute (you should monitor this), simply either:
Increase the interval time between runs or,
Use a lock file to make sure no two instances of your script can run at the same time.
if (($fp = fopen('/tmp/mylockfile', "r+")) === false) {
die("Could not open lock file");
}
if (!flock($fp, LOCK_EX | LOCK_NB)) {
die("Could not obtain lock");
}
// run your code here
// release the lock and close file
fclose($fp);
OTOH If the script needs to run more than once per minute, you would need a different mechanism entirely.
Q: What is the best way to run a PHP script at a particular time, or interval?
A: Use cron
Q: Does a cronjob create a big load on the server?
A: Depends off course off your script. But checking if an auction should be closed, close it and send two emails shouldn't be to difficult. Be sure to create some kind of lockfile to make sure that if your script runs longer than the interval set, it isn't run twice.
Q: running a script with shorter intervals than 1 minute
A: Can't answer this one for you. Sorry :)
Use Cron. It allows you to run any command at most once per minute: http://clickmojo.com/code/cron-tutorial.html
As far as server load goes, it generally won't be a concern unless you are running a massive number of database calls very often on a very low-end server. I speak in generalities, but the idea is sound.
If you are using something else (besides PHP) to run your auction timer mechanism, I recommend you attach some code to that timer mechanism that also executes a mail-sending script when the timer runs down to zero and determines a winner.
Run the PHP script as a command line script. This will not put a load on the webserver - just a load on the server and you can easily run it via CRON.
If you add #!/usr/bin/php to the top of the script and change the execute bit on the file with chmod +x scriptname.php you can directly execute the script without passing it through php
http://php.net/manual/en/features.commandline.php
A couple of things you need to do this:
Store something in your auction information indicating whether you've sent this e-mail yet or not (could be a boolean or a date for when it was sent which might be null). Although I have to assume you need to do something besides send this e-mail? Like mark the auction as closed so no more bidding can take place?
A bit of code that finds auctions which need this e-mail sent: e.g. they've ended and have not yet been reminded.
Something to repeatedly execute the bit of code in 2. You could use cron. Alternatively you can write a pretty simple daemon for unix that runs constantly in a loop of (wait at least a few ms or more; do some stuff). The latter is a lot more work but in my opinion scales much better. See http://pear.php.net/package/System_Daemon for some useful tools if you're interested in this approach.
One thing to consider is how much you want to be careful about accidentally double-sending this e-mail. If you're only running this code in a single thread it's pretty easy but if you ever want to build out to the point where you have several different distributed machines that create and send these e-mails you have to be a bit more careful. If you're running it out of cron can you guarantee one run of it will always be finished before another one starts?
I have a PHP script that needs to be executed by the end of every month. How would I do that without using cron on Unix-like systems or Task Scheduler on Windows systems? Isn't there some built-in feature in php for this? Because using cron/scheduler is not that much portable way IMO.
The only other way is by triggering it when the website is loaded. For example, you'd store the time the script was last run. Then every time a page is loaded, you'd check if it's time to run it. If so, then you would run it as part of the page load. Of course, this depends on (1) the task being a very quick one, and (2) that the task doesn't have to be run exactly on schedule, down to the second. This is basically how wp_cron() works in Wordpress.
Php is just a scripting language, not a process that is aware of time and may trigger events at desired moments.
Once you settle in a server, you don't have to worry about portability: migrating to another place won't be an automatic process because the environment could be very different.
So stick with cron, or write yourself a OS-agnostic layer.
In the system i worked on, i had a little module that had the last running of the script saved, and on every running of the main script, it checked, if the script shouldn't have been run. In case it should have, it did before anything else executed, so the system had the right data anyway, even if the periodical script wasn't run "on time". It also checked if the script shouldn't have been run more than once, and ran it several times, if needed.
A bit crude, but produces the right results without anything but PHP/mysql.
As my server is not supporting cron job, I want a file in my server to trigger its action on a particular time every day..
Please let me know whether it possible to do run a script at a particular time from the server side itself without any external act.
I agree with Kel's answer.
You could try out one of the free cronjob services available, if your server doesn't support it.
Online Cronjobs
Set Cronjob
Just the first two found on Google, there's likely to be more if you search a little.
You cannot start script without ANY external act.
If your file server has SSH or HTTP server or something like that, you can configure cron job on another server to start your script via SSH / HTTP / something like that.
Also, you can create PHP script, which would do sleeping in a loop all the time, and wake up and do some job only if current time is near some specific value. You will have to correct maximum execution time for php script (see here for details), and you will have to start your script on server startup. BTW, this does not look like good solution.
As mentioned before, this is not possible literally "without external act".
A nice solution I found in the ThinkUp software (don't know where else this is used) to use a RSS feed reader. From the point of simplicity, this is probably the best option.
The idea is that you use your feed reader to automatically call a script on your site every XX hours (or whatever interval you want). When called, this script executes the maintenance tasks or whatever it is that you want to do.
To make sure that not everybody can run that script and cause your server to break down (I suppose this is a somewhat heavy task), you can use a unique long identifier string appended as URL parameter to make sure that the script only gets called by you.
Other than that, you can use one of the "poor man's" web cron job services that have been suggested in other answers.
if (rand(0,100)==0){
if (!file_exists($tf='tmp/job.crontime') || (time() - filemtime($tf))>(60*60*24)){
... # your tasks
touch($tf);
}
}
This simple & stupid script uses a file to store the time of last job-ecexution. If >60*60*24 has passed — it launches the job code. rand(0,100) should lower the overhead of checking for jobs on each request: 1/100 is the chance of running your jobs.
Put it in the end of your 'index.php'. Don't use in projects with modelate to high load :))
The Great Disadvantage: it won't run if you don't have any visitors.
UPD: Write a script that runs indefinitely and every 30s does touch('tmp/job.crontime') to report it's still alive. It should also check the current time & perform actions.
In index.php, if more than 30s has passed — re-launch the daemon with an HTTP-request. Ugly, but fully functional. You'll also deal with time limits, be careful!
Well, if this is on a public web server and you have enough visits, you could always use those to run code to check for a given value, say hour of day, number of times a file have been accessed (or store your number in a file). Just put your php code on top of a web page.
I'm currently running a Linux based VPS, with 768MB of Ram.
I have an application which collects details of domains and then connect to a service via cURL to retrieve details of the pagerank of these domains.
When I run a check on about 50 domains, it takes the remote page about 3 mins to load with all the results, before the script can parse the details and return it to my script. This causes a problem as nothing else seems to function until the script has finished executing, so users on the site will just get a timer / 'ball of death' while waiting for pages to load.
**(The remote page retrieves the domain details and updates the page by AJAX, but the curl request doesnt (rightfully) return the page until loading is complete.
Can anyone tell me if I'm doing anything obviously wrong, or if there is a better way of doing it. (There can be anything between 10 and 10,000 domains queued, so I need a process that can run in the background without affecting the rest of the site)
Thanks
A more sensible approach would be to "batch process" the domain data via the use of a cron triggered PHP cli script.
As such, once you'd inserted the relevant domains into a database table with a "processed" flag set as false, the background script would then:
Scan the database for domains that aren't marked as processed.
Carry out the CURL lookup, etc.
Update the database record accordingly and mark it as processed.
...
To ensure no overlap with an existing executing batch processing script, you should only invoke the php script every five minutes from cron and (within the PHP script itself) check how long the script has been running at the start of the "scan" stage and exit if its been running for four minutes or longer. (You might want to adjust these figures, but hopefully you can see where I'm going with this.)
By using this approach, you'll be able to leave the background script running indefinitely (as it's invoked via cron, it'll automatically start after reboots, etc.) and simply add domains to the database/review the results of processing, etc. via a separate web front end.
This isn't the ideal solution, but if you need to trigger this process based on a user request, you can add the following at the end of your script.
set_time_limit(0);
flush();
This will allow the PHP script to continue running, but it will return output to the user. But seriously, you should use batch processing. It will give you much more control over what's going on.
Firstly I'm sorry but Im an idiot! :)
I've loaded the site in another browser (FF) and it loads fine.
It seems Chrome puts some sort of lock on a domain when it's waiting for a server response, and I was testing the script manually through a browser.
Thanks for all your help and sorry for wasting your time.
CJ
While I agree with others that you should consider processing these tasks outside of your webserver, in a more controlled manner, I'll offer an explanation for the "server standstill".
If you're using native php sessions, php uses an exclusive locking scheme so only a single php process can deal with a given session id at a time. Having a long running php script which uses sessions can certainly cause this.
You can search for combinations of terms like:
php session concurrency lock session_write_close()
I'm sure its been discussed many times here. I'm too lazy to search for you. Maybe someone else will come along and make an answer with bulleted lists and pretty hyperlinks in exchange for stackoverflow reputation :) But not me :)
good luck.
I'm not sure how your code is structured but you could try using sleep(). That's what I use when batch processing.