Using cron job to trigger a PHP script with includes
I ran across this problem on a recent job: I needed to trigger a PHP script that automatically emails me a file. However, the script is part of another script, and uses lots of includes, and also has library files that also use includes.
Normally, to trigger a php script that is standalone, all you would need to do is set up a cron job like this in your server:
:: Code ::/bin/local/php /path/to/your/php/script.php
and that would be it, whenever you wanted, the script script.php would be run by the crontab job.
However, there's a problem with this: when bash runs a crontab job, it's not going through Apache, with all its configurations, include paths and so on. So php will look for the files from the actual /bin/local/php directory, and of course won't find them.
So what you need to do in this case is the following:
Locate the path to your sh and lynx programs by typing in this on the terminal:
:: Code ::whereis sh
Try either command, one should give you the path you need. If your system doesn't have lynx, try links, w3m, or links2, those are other text mode browsers. The browsers are what will be used to open the php script, which will then run your program.
Then you'll need to create an sh file, that is what will call the php file, through lynx. We'll assume you have lynx installed on your webserver, and that the path to sh is /bin/sh and the path to lynx is /usr/local/bin/lynx.
:: Code ::#!/bin/sh
/usr/local/bin/lynx -source http://www.yoursite.com/folder/script.php
Note the ! between # and /bin/sh, #!/bin/sh.
We'll call this script cron-lynx.sh
Save that to a directory, it can be anywhere you have access to on the file server, like:
I prefer to put most scripts below the website root directory, so snoopy people can't get a hold of them.
Then create another file, called script.php. This is the file that lynx will be loading from the server when the cron job is run. This script needs to be accessible from above the site document root, in other words, you need to be able to reach it from a browser. I made mine very simple, just including the include that has the function, then the function call:
:: Code ::<?php
// I'm assuming you've already set your include path
include( 'includes/stuff/another_script.inc' );
Here are directions on how to set PHP include path on Apache.
Then I used my hoster's crontab manager, it's a gui thing, I'm lazy, shoot me !! and created this cron job:
:: Code ::/bin/sh /usr/www/yourdirectory/sh_scripts/cron-lynx.sh
There is a space between /bin/sh and /usr. I have it run once a month, and when it runs, it executes the correct procedure without a flaw. Don't ask me what happens to lynx though after the script runs, I'm not sure, I'm going to have to check on that.
More reading on this here and here.
WARNING ! ! Check the sh and php first
Make sure you debug and test your sh and php scripts thoroughly before setting up the cron job. You can test your cron job by logging onto your server through ssh, then running the same command you will use above to run the cron job.
Once it's solid, set up the crontab job, and you shouldn't have to think about it again.
Better living through unix/linux....
Back to top
Update: although the above method worked fine through ssh when I tested it, for some reason it wouldn't work as a cron job.
I found a solution, which involves using wget instead of lynx to do the job, that works fine:
:: Code ::#!/bin/sh
/usr/local/bin/wget -q -t 5 --delete-after http://www.mysite.com/data/send_file.php
Note the syntax here:
#!/bin/sh #! then the path to the sh executable, gotten by which or whereis
Then the path to the wget:
Then some switches:
-q quiets output, for testing purposes delete this until you have it running, that will give you error output without it. None with it.
-t 5 is how many retries before giving up, in this case 5 retries
--delete-after shuts it down after the job runs. I think this is the switch that made this work through cron, although I'm not positive.
Then the web accessible path to the php file.
This cron job fired successfully last night so it seems to be a good solution.
Back to top
a far more simple solution
just run the cronjob with the command
and in the the php file use the script document root
do not use, _SERVER["DOCUMENT_ROOT"], it will not return you the correct value for a script running through cronjob
Back to top
All times are GMT - 8 Hours