Cronless Cron???

Discussion in 'PHP' started by peeg, Jun 4, 2007.

  1. #1
    Hey Guys

    Working on a project and hit a snag! Basically, I'm looking at a script that runs another script every day. I can't use cron jobs though, that's the only thing.

    I've been looking into this and have found the plugin wp-autoblog has managed to use "cronless cron jobs" to do exactly what I'm wanting, but it's in Wordpress and uses a plugin called wp-cron.

    I'm looking for any information or tips about how to run a cronless cron job.

    Thanks

    Rich
     
    peeg, Jun 4, 2007 IP
  2. ZenOswyn

    ZenOswyn Peon

    Messages:
    50
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #2
    It's a tough thing to do if you want it to be reliable.

    The only alternative I'm aware of (which is probably how the wordpress plugin works) is to configure a PHP script to only run the first time it is visited each day, or after 12 hours. This is most easily done by modifying a file each time the script is run.

    If the modification date of the file is older than a specific time period, or from a previous day/week/month then the PHP script will run again.

    It's a bit of a hack, and if nobody visits the site, it won't run.
     
    ZenOswyn, Jun 4, 2007 IP
  3. peeg

    peeg Peon

    Messages:
    1,064
    Likes Received:
    43
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Yeah, I'm looking for something that's automatic like what cron is.

    Bummer lol
     
    peeg, Jun 4, 2007 IP
  4. mrmonster

    mrmonster Active Member

    Messages:
    374
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    60
    #4
    Might want to specify what OS you are using, there will be a big difference.

    I don't see a way to do it without some external tool/service running in the background and executing a PHP file at some interval.

    You could always try, as mentioned, doing a check on every visitor to see if a job needs to be executed. Should be fairly simple and reliable unless you need things to happen with a very specific interval.

    The most efficient way to do this is to use a plain file text file on the filesystem and simply writing, overwriting, to it a timestamp. Then on the each visit read the file and do some logic based on whats there.
     
    mrmonster, Jun 4, 2007 IP
  5. rodney88

    rodney88 Guest

    Messages:
    480
    Likes Received:
    37
    Best Answers:
    0
    Trophy Points:
    0
    #5
    rodney88, Jun 4, 2007 IP
  6. decepti0n

    decepti0n Peon

    Messages:
    519
    Likes Received:
    16
    Best Answers:
    0
    Trophy Points:
    0
    #6
    What Zen said would work though, since, if nobody visits the site, it wont update, and nobody's going to know it hasnt been updated. Just when someone arrives, check if it's been long enough that you should update it, and if it has, then do it before the page loads (and update whatever timer etc)

    edit: Alright, pretty much what mrmonster said
     
    decepti0n, Jun 4, 2007 IP
  7. ansi

    ansi Well-Known Member

    Messages:
    1,483
    Likes Received:
    65
    Best Answers:
    0
    Trophy Points:
    100
    #7
    i had to do this for a project of mine. basically i have a table named tbl_updates and a row name last_updated. int(11) storing a unix timestamp. each time the script is run i connect and check to see if date("d",$timestamp_in_db) == date("d",time()).. if the number of the day is the same, return. if not, perform an action. for me it was deleting expired rows
     
    ansi, Jun 5, 2007 IP
  8. ansi

    ansi Well-Known Member

    Messages:
    1,483
    Likes Received:
    65
    Best Answers:
    0
    Trophy Points:
    100
    #8
    here, i will post my little function for it.

    
    function clean_db()
    {
    	$query = "select clean_date from tbl_last_clean";
    	$result = mysql_query($query) or die('[{error:"Error (select): '.mysql_error().'"}]');
    	$row = mysql_fetch_row($result);
    
    	if ( empty($row[0]) )
    	{
    		$query = "insert into tbl_last_clean(clean_date) values('".time()."')";
    		$result = mysql_query($query) or die('[{error:"Error (insert): '.mysql_error().'"}]');
    		
    		if ($result) 
    			return;
    		else
    			echo '[{error:"Error during db clean."}]'; exit;
    
    	}
    	else
    	{
    		if( date("d",$row[0]) != date("d",time()) )
    		{
    			$query = "delete from tbl_mytable where expire < '".time()."'";
    			$result = mysql_query($query);
    			
    			$query = "update tbl_last_clean set clean_date = '".time()."'";
    			$result = mysql_query($query);
    		}
    		else
    			return;
    	}
    }
    
    PHP:
    hope this helps you some.
     
    ansi, Jun 5, 2007 IP
  9. peeg

    peeg Peon

    Messages:
    1,064
    Likes Received:
    43
    Best Answers:
    0
    Trophy Points:
    0
    #9
    Hi!

    Well I don't think the page is going to be accessed all that often. Is there any way that I can run cronless cron without the page being accessed?

    Rich
     
    peeg, Jun 5, 2007 IP
  10. jestep

    jestep Prominent Member

    Messages:
    3,659
    Likes Received:
    215
    Best Answers:
    19
    Trophy Points:
    330
    #10
    If you have a crappy spare computer lying around, you can load Linux on it and have it cron the page at a certain interval. Definitely a bit ugly but it would get the job done for really cheap.
     
    jestep, Jun 5, 2007 IP
  11. krt

    krt Well-Known Member

    Messages:
    829
    Likes Received:
    38
    Best Answers:
    0
    Trophy Points:
    120
    #11
    You want the script to make blog posts, yes? (judging by the mention of wp-autoblog plugin in first post). These only get seen when a user accesses the page anyway so what is wrong with waiting for a page access?

    If not, then find a free hosting service with cron support or find someone who can add a crontask on their host to trigger the "psuedo-cron" on your page at the correct time.
     
    krt, Jun 5, 2007 IP
  12. mrmonster

    mrmonster Active Member

    Messages:
    374
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    60
    #12
    If you have SSH access to the server and can execute shell scripts you could always write a shell script that executes, which in-turn executes a php script.

    
    #!/bin/bash
    # This is timer.sh script, executes your PHP file every 60 seconds
    
    # execute your PHP code
    /usr/bin/php /home/myaccount/timed.php
    
    # wait 60 seconds
    sleep(60)
    
    # execute self, creates an execution loop that doesn't kill the system
    ./home/myaccount/timer.sh
    
    
    Code (markup):

    This should work quite well until the server reboots, you would have to start it up again since you don't have cron, or the server admin kills it.
     
    mrmonster, Jun 5, 2007 IP
  13. KalvinB

    KalvinB Peon

    Messages:
    2,787
    Likes Received:
    78
    Best Answers:
    0
    Trophy Points:
    0
    #13
    To run crons on my godaddy account I have a windows machine at home that has scheduled tasks that run local php scripts. Those php scripts post/get to the cron scripts on the godaddy account so they run.

    cURL is good for doing that sort of thing.

    
    function http_post($path, $params,$get="",$host="")
    {
    	// Initiate CURL
    	$ch = curl_init();
    
    	// Set flags
    	if($get)
    		curl_setopt($ch, CURLOPT_HTTPGET,        1);
    	else
    		curl_setopt($ch, CURLOPT_POST,        1);
    
    	
    	$header[] = "Accept: */*";
    	$header[] = "Accept-Language: en-us";
    	$header[] = "UA-CPU: x86";
    	$header[] = "Accept-Encoding: gzip, deflate";
    	$header[] = "Host: $host";
    	$header[] = "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)";
    	$header[] = "Connection: Keep-Alive";
    
    	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    	curl_setopt($ch, CURLOPT_HEADER, 0);
    	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    	curl_setopt($ch, CURLOPT_TIMEOUT, 300); 
    	
    	// Pass our values
    	curl_setopt($ch, CURLOPT_URL,            $path);
    
    	if($params != "") curl_setopt($ch, CURLOPT_POSTFIELDS,     $params);
    
    
    	$content = curl_exec($ch);
    
    	curl_close($ch);
    	
    	return array("body" => $content);
    }
    
    Code (markup):
    When posting to godaddy, if you don't have the correct headers or post to quickly too often (more than a couple requests per second) they'll block you. It's some kind of DDOS protection they have set up.
     
    KalvinB, Jun 5, 2007 IP
  14. jestep

    jestep Prominent Member

    Messages:
    3,659
    Likes Received:
    215
    Best Answers:
    19
    Trophy Points:
    330
    #14
    Just out of curiosity, would file_get_contents not work in that situation? It seems that curl is a bit of overkill for just accessing a web page on another server.

     
    jestep, Jun 5, 2007 IP
  15. KalvinB

    KalvinB Peon

    Messages:
    2,787
    Likes Received:
    78
    Best Answers:
    0
    Trophy Points:
    0
    #15
    godaddy has too many checks in place to make sure requests are real and not robot generated. other hosts may be more lenient.

    file_get_contents might work. I know cURL works.
     
    KalvinB, Jun 5, 2007 IP
  16. mrmonster

    mrmonster Active Member

    Messages:
    374
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    60
    #16
    Duno this remove method seems a little crude to me.

    If you want to get silly, you could simply do...

    
    
    // add code to check if recursion should be stopped
    // check a config file or db for a flag weather actions should continue
    
    // your timed code logic here
    print "wooo executed!";
    
    // wait 60 seconds after doing the work
    sleep(60);
    
    // call self again
    file_get_contents($_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"]);
    
    PHP:
    :)

    You could add some error checking and even pass data from each call to the next.

    Now we're getting a little crazyyyyyyyyyy :)
     
    mrmonster, Jun 5, 2007 IP
  17. jestep

    jestep Prominent Member

    Messages:
    3,659
    Likes Received:
    215
    Best Answers:
    19
    Trophy Points:
    330
    #17
    Wouldn't continuously looping like this keep using up memory until the script is killed, or you run out?
     
    jestep, Jun 5, 2007 IP
  18. mrmonster

    mrmonster Active Member

    Messages:
    374
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    60
    #18
    Theres no actual PHP loop, it just does recursive calls.

    As soon as it does the call the script that did the call ends, takes no more resources than a page refresh in the browser. One instance of the script always stays in memory, but its very light and theres no CPU hogging during the sleep() time.
     
    mrmonster, Jun 5, 2007 IP
  19. Joobz

    Joobz Peon

    Messages:
    598
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    0
    #19
    I have a windows script (small exe) that you can set a task on which will open any url you specify. You're welcome to it if you want.
     
    Joobz, Jun 5, 2007 IP