Part of the EllisLab Network
   
1 of 2
1
cron script?!
Posted: 26 May 2006 04:31 AM   [ Ignore ]  
Grad Student
Rank
Total Posts:  86
Joined  05-26-2006

I’m new to Code Igniter, just playing around with it till I’m comfortable.

I wanted to ask, suppose I make an application(using CI ofcourse) which has some DB magic & other stuff. Now, I also want a script to be run at specific intervals, so that’ll be run via a Cron tab. Now, the thing is that CI has an index file & that accepts the clean URIs & loads controllers etc. But if I want to run a cron, its gotta be a file, no? And so how would I go about writing code in that? Any suggestions? Or will I’ve to use all PHP code including the mysql_* functions instead of the DB abstraction etc of CI?

Profile
 
 
Posted: 26 May 2006 04:36 AM   [ Ignore ]   [ # 1 ]  
Grad Student
Rank
Total Posts:  61
Joined  03-13-2006

Off the top of my head, if u need to execute a file, why dont you just have a php file that calls the proper CI url ?

Example

<?Php
   http
://index.php/cron/dothis
?>
Profile
 
 
Posted: 26 May 2006 04:56 AM   [ Ignore ]   [ # 2 ]  
Grad Student
Rank
Total Posts:  86
Joined  05-26-2006

hmm yeah, that is a scenario that I thought of. but wasn’t sure of it. so I thought that I’d ask the people here if they know of a tried & tested way or can suggest anything.

also, usually crons in my applications do some heavy duty work & are likely to timeout, so I reset the timeout limit in the script via set_time_limit(). would that be a problem if I do that inside a controller?

Profile
 
 
Posted: 26 May 2006 05:19 AM   [ Ignore ]   [ # 3 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  547
Joined  03-08-2006

If you need a part of your script to be run under cron, you will probably want to have one of your controllers set up to do this, but implement some form of security to check IP of the cron machine or whatever.

To run it, you probably have access to wget or curl, so use that (replace with whichever command line fetcher you have): wget http://example.com/index.php/cron/dothis

This article might help.

 Signature 

Twitter | Flickr | Last.fm | Del.icio.us

Profile
 
 
Posted: 26 May 2006 06:22 AM   [ Ignore ]   [ # 4 ]  
Grad Student
Rank
Total Posts:  86
Joined  05-26-2006
Craig - 26 May 2006 05:19 AM

If you need a part of your script to be run under cron, you will probably want to have one of your controllers set up to do this

Is this gonna be any different than writing a controller to be executed via a HTTP call in a browser?

Craig - 26 May 2006 05:19 AM

To run it, you probably have access to wget or curl, so use that (replace with whichever command line fetcher you have): wget http://example.com/index.php/cron/dothis

nah, my host doesn’t allow wget. cron scripts are executed by PHP directly like

/usr/local/bin/php /full/path/to/public_html/mycron_sayhello.php
Profile
 
 
Posted: 26 May 2006 09:26 AM   [ Ignore ]   [ # 5 ]  
Grad Student
Avatar
Rank
Total Posts:  38
Joined  04-06-2006

Just write your cron scripts outside of Code Igniter. Seems simple enough, no? Then you can store them outside the web root, and not have to worry about people remotely accessing them.

Profile
 
 
Posted: 26 May 2006 09:52 AM   [ Ignore ]   [ # 6 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  137
Joined  05-20-2006

I suspect that you will need to seperate the processing functionality of your code from the user interface here if you really want to get your code executing in CRON.  The fact is that the controllers are only really valuable when dealing with user interaction.  What you may want to do is put all your processing logic into functions that are referenced as Plug-Ins in CI, but can be called through a traditional PHP include in a sepeate script that you can execute via CRON.  Remember, CRON is faceless so there is no point in burdening the scripts with any UI stuff. 

Myles

 Signature 

Myles Wakeham
CTO/CEO
Arizona Web Developers Edgeneering, LLC
Podcast Hosting at CyberEars.com

Profile
 
 
Posted: 26 May 2006 10:46 AM   [ Ignore ]   [ # 7 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  886
Joined  03-06-2006

If it must be run from a cron script, it could be in any language that has an interface to your database. Not only PHP, but Perl, Ruby, even shell scripts.

For example, a simple cleanup could easily be done by a shell script accessing MySQL directly.

It depends on what you want to do.

 Signature 

Corozal, Belize | Linux.bz | Using Kubuntu Linux 7.10 | CodeIgniter 1.5.3

Profile
 
 
Posted: 26 May 2006 12:42 PM   [ Ignore ]   [ # 8 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  130
Joined  04-14-2006

You can always do (simplified):

#!/usr/bin/php
<?php
fclose
( fopen("http://mysite.com/codeigniter/controller/cronmethod") );

?>


One thing I’ve noticed with web developers though: many of the times when people think they need cron scripts, they don’t really. For example, say you have a new user signup link, that emails people a validation code that’s valid for 2 hours. You don’t need a cron script to handle this. All you need, is to run a query that deletes all the validation codes older than 2 hours to run just before you attempt to check a validation code. No one may visit that page for 3 days, and you could have codes that are 3 days old .. but it doesn’t matter, because by the time something goes to use them, they’ll get deleted.

There are a number of benefits to this method: you avoid a bunch of points of failure like the cron script not running/working, perhaps the machine was being rebooted or otherwise down at the time the script would normally run (well, assuming you’re not using anacron), it doesn’t require cron access (which can be hard to get in a shared hosting environment).

MVC can help out with this a lot too, because if you put in your model, and you only have the one model that accesses the data, then you can ensure that anytime you pull records via the model, your cleanup routines can run to ensure no old/stale/inappropriate data is returned.

If you’re still really 100% sure that there’s no way around not using cron, then see above smile

 Signature 

CIForge.com - CodeIgniter Community Source Hosting

Profile
 
 
Posted: 26 May 2006 02:34 PM   [ Ignore ]   [ # 9 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  547
Joined  03-08-2006

Greg: Then you have the potential for the innocent user seeing an error message of some sort if something doesn’t go right.

 Signature 

Twitter | Flickr | Last.fm | Del.icio.us

Profile
 
 
Posted: 26 May 2006 03:43 PM   [ Ignore ]   [ # 10 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  130
Joined  04-14-2006
Craig - 26 May 2006 02:34 PM

Greg: Then you have the potential for the innocent user seeing an error message of some sort if something doesn’t go right.

In production sites, you shouldn’t be showing users error messages. At most, if you have a fatal error say “sorry something went wrong, please try again”. Errors should be logged/emailed to admin.

Besides, with that logic, the error will simply be “shown” to the cron script, and you’ll still have no idea something didn’t work.

 Signature 

CIForge.com - CodeIgniter Community Source Hosting

Profile
 
 
Posted: 26 May 2006 05:23 PM   [ Ignore ]   [ # 11 ]  
Grad Student
Rank
Total Posts:  86
Joined  05-26-2006

[quote author=“bgmccollum”]Just write your cron scripts outside of Code Igniter. Seems simple enough, no? Then you can store them outside the web root, and not have to worry about people remotely accessing them.

yeah well, writing cron scripts outside of CI will mean that I’ll have to loose the DB abstraction & will either have to use the PHP functions directly or include and initiate the DB class & any other class seperately. read my first post where I mention this!! smile

[quote author=“Myles Wakeham”]I suspect that you will need to seperate the processing functionality of your code from the user interface here if you really want to get your code executing in CRON.  The fact is that the controllers are only really valuable when dealing with user interaction.  What you may want to do is put all your processing logic into functions that are referenced as Plug-Ins in CI, but can be called through a traditional PHP include in a sepeate script that you can execute via CRON.  Remember, CRON is faceless so there is no point in burdening the scripts with any UI stuff. 

yes, that looks like a viable solution. or the functions can be loaded as helpers as well? can you please provide a basic example of how I’d go about that? I haven’t used plugins or helpers with CI yet, so not sure how I can have a plugin or helper for CI & yet reference it outside in a script without invoking any controllers, all the while being able to access any of CI’s features/classes.

[quote author=“linuxbz”]If it must be run from a cron script, it could be in any language that has an interface to your database. Not only PHP, but Perl, Ruby, even shell scripts.

For example, a simple cleanup could easily be done by a shell script accessing MySQL directly.

It depends on what you want to do.

yeah, I know. but the thing is that its been ages since I last used Perl, never actually liked it. I haven’t really started in Ruby yet(& its not available on that webserver). the point is about writing less code for more work. thats what we have reusable classes for, to write stuff quickly. smile

Profile
 
 
Posted: 03 June 2006 02:46 PM   [ Ignore ]   [ # 12 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

Here is how I run cron scripts in the CI environment, it ended up being very easy:

cron scripts are generally going to be doing maintenance things such as database updates, cache file management, sending emails, etc. Things with generated output like emails I want to come from view files. The db updates will use existing data models. cache file cleaning will use custom CI libraries. Therefore, it is important to me to have the CI environment available to my cron script.

What is not necessary is an HTTP connection. Why involve the web server? All you are doing is adding an unnecessary TCP stack setup and teardown, creating unwanted access_log entries, not to mention more security checks and timeout issues.

The slight problem is that CI expects an HTTP connection environment to make everything work happy. But actually, all CI really needs for a cron script is the PATH_INFO. That is how CI knows what controller/method to use, etc. So, we can emulate this.

First, make a directory for your cron scripts. I just used scripts and put it in the same directory that my CI system folder is in. Then, copy the index.php file from your DOCUMENT_ROOT (the script that normally initiates a connection to CI from a web browser) to the scripts directory, and rename it to something meaningful, such as clean_cache.php.

Now, we edit this file and make some slight adjustments. First, we don’t want the script to timeout during execution, so somewhere toward the top we add:

set_time_limit(0);

Next, we need to set the path to the system folder, if it isn’t correct:

$system_folder = "../system";

Next, we need to let CI know what controller/method we want to access, and any other URI variables we need. Normally this happens in the URL, so we emulate it by setting PATH_INFO manually:

$_SERVER['PATH_INFO'] = '/cron/cleancache';

Next, you create a cron.php controller (in the system/controllers dir) with a cleancache method, and make it do what it needs to do. load libraries/models/etc, execute them, then exit. What you don’t want to happen is output anything. Just make sure you don’t echo any content to stdout (echo, loading views, etc.) If you are sending emails, you would load a view file, but return the contents to a variable instead of displaying it (pass true as third param), then run through normal procedures for sending emails.

One thing to be aware of regarding security, you probably don’t want anyone accessing /cron/cleancache from a web browser, so in the cron.php controller constructor, you may want to do some kind of check to make sure we are coming from a cron script. Probably the easiest method would be to test the SCRIPT_FILENAME variable:

if($_SERVER['SCRIPT_FILENAME'] != 'clean_cache.php')
  exit;

Once everything looks good, add your crontab entry to execute the script, and there you have it!

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 03 June 2006 05:11 PM   [ Ignore ]   [ # 13 ]  
Grad Student
Rank
Total Posts:  86
Joined  05-26-2006

that certainly looks quite easy mohrt, thanks. smile I’ll play with it & see how it goes as well as some other suggestions made when I next get time to play with CI!! smile

Profile
 
 
Posted: 29 September 2006 10:02 AM   [ Ignore ]   [ # 14 ]  
Summer Student
Total Posts:  8
Joined  03-20-2006
mohrt - 03 June 2006 02:46 PM

Next, we need to let CI know what controller/method we want to access, and any other URI variables we need. Normally this happens in the URL, so we emulate it by setting PATH_INFO manually:

$_SERVER['PATH_INFO'] = '/cron/cleancache';

That didn’t worked for me, instead I used:

putenv('PATH_INFO=/cron/cleancache');
Profile
 
 
Posted: 29 September 2006 10:05 AM   [ Ignore ]   [ # 15 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006
Thijs W - 29 September 2006 10:02 AM
mohrt - 03 June 2006 02:46 PM

Next, we need to let CI know what controller/method we want to access, and any other URI variables we need. Normally this happens in the URL, so we emulate it by setting PATH_INFO manually:

$_SERVER['PATH_INFO'] = '/cron/cleancache';

That didn’t worked for me, instead I used:

putenv('PATH_INFO=/cron/cleancache');

Works for me PHP 5, Linux/Apache. What are you using?

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
   
1 of 2
1
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 819, on March 11, 2010 11:15 AM
Total Registered Members: 120612 Total Logged-in Users: 50
Total Topics: 126647 Total Anonymous Users: 3
Total Replies: 665760 Total Guests: 498
Total Posts: 792407    
Members ( View Memberlist )