tags:

views:

40

answers:

4

I do not have access to cron jobs as I am on a shared server. I would still like to run an update task on my database at set intervals. How can I best achieve this. Obviously I could check the time in which index.php is executed and if it is on the hour I could include my update script. But then there is a risk of the script not executing (no users request a page at that second) or many executions.

Any ideas?

A: 

Run a script on a server that does have cron to access a url that runs the php script on the hour. I use wget in my crontab to do that sort of thing.

Paul Tomblin
Hmmm, thats a pretty good idea... I don't know much about cron jobs though. So if anyone has a pure PHP solution then that would be awesome.
Pablo
A: 

You're part of the way there. Don't check if the time is "on the hour"; check the difference between the current time and the time of the last update. This, of course, requires you to store a timestamp somewhere when you run the update.

The biggest problem with this approach is that the page won't load until the update is complete. Depending on how long the update takes, this might not be a factor; but if it is, you might want to spawn a new thread for the update (I'm not even sure if that's possible in PHP).

Mike Baranczak
I have considered the 'spawning a new thread' thing. I think I'll be ok if I slap the update at the bottom of the page. The page will continue to load for the user... but they should see the output above it. There is still a problem however. What if two users load the page at the same time... then they will both run the update task..
Pablo
Make it a url that only you access, and `wget` it from another system (I use my home Linux box for this) every hour. Then it doesn't matter how long it takes to render.
Paul Tomblin
@Pablo: This will depend on the server, but I think most of them buffer the script output, so they won't send the page to the client until the script finishes. A alternate way would be to put the update script in a separate page, then have the main page load that (perhaps into a 1x1 iframe at the bottom of the page.)
Mike Baranczak
the 1x1 iframe is a cheeky solution, but I like it.
Pablo
+2  A: 

Are you sure you don't have access to cron?

crontab -e

You just might...

Edit: Also, Please don't attach an update script to index.php at one poor user's expense every hour...

andyortlieb
+1 Agree to not prolonging the load time!But I'm going to assume that he knows about his own Cron... :)
Evan
Thanks Evan. I wish I could agree with you about the bit regarding knowing his own cron, but he stated in another comment that he doesn't know much about cron itself. I speculate it's likely that he is not aware of the user level crontab. If so, I hope that he'll look into it since it is the prudent way to schedule a job on a unix system--assuming that job must be scheduled and not triggered for some reason...
andyortlieb
A: 

You guys are close. Rather than put the periodic functions in the actual PHP of the page the user is requesting, have a javascript request happen from the user's page. This way, you can be certain that the page load will not be slowed down, and the javascript will fire onLoad(). Keep the stored 'last processed' value as suggested above, and only run the cron function once in a given interval.

Here's the JS to use to call something remotely. It will only work in modern browsers with JS enabled of course...

<script>
        function DoCron()
        {
            var xhr; 
            try {  xhr = new ActiveXObject('Msxml2.XMLHTTP');   }
            catch (e) 
            {
                try {   xhr = new ActiveXObject('Microsoft.XMLHTTP');    }
                catch (e2) 
                {
                  try {  xhr = new XMLHttpRequest();     }
                  catch (e3) {  xhr = false;   }
                }
             }

            xhr.onreadystatechange  = function()
            { 
                 if(xhr.readyState  == 4)
                 {
                      if(xhr.status  == 200) 
                      {
                            alert("Cron Worked");
                      }
                      else 
                      {
                         return 'ERROR';
                      }
                 }
            };  

            xhr.open("POST", "CRON.php", true); 
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    
            xhr.send('');
        }

    </script>
Evan
-1: Relying on your clients for maintenance, and microsoft dependence.
andyortlieb
The MS stuff is there for a special case. Works fine in Safari, Chrome, etc as well. From earlier responses, it seems that he's unwilling to use WGET or something that would put the load on the 'admin'. This was an attempt to remove the processing load from users' load time
Evan
Eh... fair enough since it's on point with what he's asking for. It's just so weird and hacky, but probably not your fault since it's on point with what he's asking for.
andyortlieb
Yeah, it's still a st of strange constraints...
Evan