skip to content

 Web design 

Database-driven systems

Easy-to-maintain web sites


 



Blog

PHP Job Scheduler (overcoming the limitations)

Public
Posted by Chris (chris) on Feb 27 2009
Blog >> Public

PHP Job Scheduler provides an option (or an extension) to CRON but it may not work on your site. I have a solution.

Where To Find It
Their website is: http://www.phpjobscheduler.co.uk/


Why Use It?
If you just want to schedule one or two jobs and if your Hosting Service provides CRON, you may just want to use CRON. On the other hand, if your ISP limits the number of CRON jobs (or doesn't provide it all), then PHPJobScheduler provides an alternative. That was the reason that I started using it. If your Web Host allows the use of included URLs (see below) then one copy of the system can schedule jobs on multiple domains and sub-domains.


How it Works
You can set this up so it is triggered when one or more pages on your web site is accessed. Every time that it is triggered, it checks if anything is scheduled or overdue. If so, it runs the program that was scheduled. There is a control panel for PHP Job Scheduler where you can schedule new jobs or make changes to an existing scheduled job.

My Web Host limits the number of Cron jobs, so I use PHP Job scheduler and I use CRON to trigger it.


Limitations
There are a few limitations that may limit its usefulness:

  1. If you use your web site to trigger the program, you need adequate traffic to your site or it won't get triggered when you expected it to. If you have Cron available, then you could use that to trigger PHPJobScheduler.
  2. If you are running a long process, then your webpage will freeze while the process runs. This may be just once a day (depending on often the job is set up to run), but for the user who was unlucky enough to trigger it, he/she may have a long wait until it finishes.
  3. If your Hosting Service blocks the include of URLs as a security precaution (allow_url_include=off in php.ini/phpinfo) then PhpJobScheduler will only work if you place a copy of the system in every domain and sub-domain where you wish to schedule a job. You must then use relative URLs in the address of the program to be scheduled. This is obviously a significant limitation. I found a way around it as outlined below.

What To Do If Your Web Host Blocks Included URLs
As mentioned previously, allowing included URLs is a security risk so many Web Hosting services block it by turning the allow_url_include parameter off. This cripples PHPJobScheduler but there is a way around it:

  1. You need to check with your ISP that they allow you to use a local php.ini file (or just try it). If you can, then you can use that to provide an allow_url_include=on parameter in the PHPJobScheduler directory.
     
  2. You can optionally use the approach that I have used to prevent this from being a security exposure for your site.

Limiting the Security Risk (of using allow_url_include)

The Borrom Line
From my experimenting, I couldn't find a way to run a single CRON job that would trigger the scheduled jobs and close the security exposure. It requires 3 CRON jobs to do it. If you run it manually or if you trigger it from your site, then you can do it with one job. 

The Details
I found that the only way to do it (using CRON) was to run three CRON jobs:

  1. The first makes the php.ini file(s) available.
  2. The second runs firepjs.php (the initial phpjobscheduler program to start scheduled jobs).
  3. The third makes the php.ini file(s) unavailable so that allow_url_include is no longer turned on. 

My hosting service allows me to run a CRON job every 15 minutes so I have the three jobs 15 minutes apart (creating a 30 minute exposure per day). I put a 400 permission on the php.ini files. I also put password control on the pjsfiles directory (in phpJobScheduler) and I changed the permission on both the phpJobScheduler and pjsfiles directories to 750 to prevent casual access through the internet. CRON requires a 775 permission on the jobs that it runs so the permission on the directories provides additional protection around the programs and the ini files. These permissions also prevent access to add or change a schedule in phpJobScheduler so they would need to be temporarily relaxed in order to make a change.

I put a php.ini file in both the phpjobscheduler and pjsfiles directory. You may not need the first one but I had it working that way so I left it.  


The Manual Approach
The approach outlined in this section could be used if you are prepared to trigger the process manually. It would probably work if you have the initial program in a frame within an exsiting page. This allows you to use a capability that is turned off in your Web Host's php.ini but they allow you to over-ride it with a local php.ini file in the directory for the program that needs that capability (in this case allow_url_include).

If you put a php.ini file into your PHPJobScheduler directory containing the statement:
allow_url_include=on

then PHPJobScheduler will be able to schedule jobs using full URLs (http://...) but there is then a security exposure that could be exploited by hackers.

This can be limited if the php.ini file is only defined when you need to run PHPJobScheduler. I accomplished this by adding three modules to PHPJobScheduler (in the main directory):

  1. The first module renames the php.ini module from some other name to php.ini.  It then uses a meta http-equiv=refresh command to start the second module.
  2. The second module "includes" the PHPJobScheduler module firepjs.php. That module initiates the process to check if there are scheduled jobs that are due to be run. When control returns to this module, it does a meta refresh for the third module.
  3. The third module renames the php.ini module back to some other name (the same name expected by the first module).

I now have this working and it seems to do the job. In my experimenting, I found that you couldn't do the rename of the php.ini module within the same module where you needed the extra access (or where you had already used that access). Thus, the two extra modules and the meta refresh became necessary. You need to trigger the new "pgm1" (whatever you call it) rather than firepjs.php to make all of this work.

The code:

pgm1  
 

<?PHP 

$curr_page_url = "http://".$_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
 $curr_dir_url = dirname($curr_page_url);

 $pgm2  = $curr_dir_url."/pgm2.php";

 echo " <meta http-equiv=\"refresh\" content=\"2;URL=$pgm2\" > ";

 if (file_exists("php.ini.disable")) {
  rename ("php.ini.x","php.ini");       
 }

 sleep (4); 

?>

pgm2  
 

 <?PHP

 require "firepjs.php";

 $curr_page_url = "http://".$_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
 $curr_dir_url = dirname($curr_page_url);
 $pgm3  = $curr_dir_url."/pgm3.php";

    
 echo " <meta http-equiv=\"refresh\" content=\"1;URL=$pgm3\" > ";

?>

pgm3  
 

<?PHP

 if (file_exists("php.ini")) {
  rename ("php.ini","php.ini.disable");       
 }

?>

 

Last changed: Mar 07 2009 at 11:00 PM

Back
 
   

Powered by Website Baker,
Design by Innovations Design based on a template by gavjof