27

I have a cron job that needs to include this file:

require '../includes/common.php';

however, when it is run via the cron job (and not my local testing), the relative path does not work. the cron job runs the following file (on the live server):

/home/username123/public_html/cron/mycronjob.php

and here's the error:

Fatal error: require(): Failed opening required '../includes/common.php' 
(include_path='.:/usr/lib/php:/usr/local/lib/php') in 
/home/username123/public_html/cron/mycronjob.php on line 2

using the same absolute format as the cron job, common.php would be located at

/home/username123/public_html/includes/common.php

does that mean i have to replace my line 2 with:

require '/home/username123/public_html/includes/common.php';

?

thanks!

gsquare567
  • 2,527
  • 3
  • 20
  • 21
  • 1
    possible duplicate of [Relative path not working in cron PHP script](http://stackoverflow.com/questions/1969374/relative-path-not-working-in-cron-php-script) – Alastair Irvine Mar 19 '14 at 06:15
  • 1
    try: chdir(__DIR__); from: [http://stackoverflow.com/questions/5254000/php-how-to-set-current-working-directory-to-be-same-as-directory-executing-the][1] [1]: http://stackoverflow.com/questions/5254000/php-how-to-set-current-working-directory-to-be-same-as-directory-executing-the – Michal - wereda-net Jul 29 '14 at 10:18

6 Answers6

32

Technically seen the php script is run where cron is located; ex. If cron was in /bin/cron, then this statement would look for common.php in /bin/includes/common.php.

So yeah, you'll probably have to use fullpaths or use set_include_path

set_include_path('/home/username123/public_html/includes/');
require 'common.php';
Robus
  • 7,277
  • 4
  • 42
  • 63
  • 1
    to make debugging easier, can i say this: if(file_exists('/home/username123/public_html/includes/common.php')) { set_include_path('/home/username123/public_html/includes/'); require 'common.php'; } else require '../includes/common.php'; or do i need to change it manually every time and do this: // LIVE set_include_path('/home/fini7463/public_html/includes/'); require 'common.php'; // DEBUG //require '../includes/common.php'; ? – gsquare567 Jun 25 '10 at 15:27
  • Im guessing the first one should be fine – Robus Jun 26 '10 at 10:10
28

nono. you need to use absolute paths on crons.

what I do is:

// supouse your cron is on app/cron and your lib is on app/lib
$base = dirname(dirname(__FILE__)); // now $base contains "app"

include_once $base . '/lib/db.inc';

// move on
Gabriel Sosa
  • 7,706
  • 3
  • 36
  • 48
  • 1
    No you don't... but you have to allow for the fact that you might be running in a different directory, and with a different include_path – Mark Baker Jun 25 '10 at 14:36
  • yeah you are right, I think a better wording could be *its recomended* instead *you need*. well I always try to do that – Gabriel Sosa Jun 25 '10 at 16:51
  • I tried your's but it still didn't work for me, so i used @Robus answer which worked fine – Ebuka Aug 04 '20 at 19:45
23

With all do respect to all the current answers, they all went to "change the php code" approach.

I don't like to change my PHP files just to run it from a cron because it reduces the code portability and increases the chances to forget to change one or two relative paths and break the program.

Instead change the directory at the cron tab line, and leave all your relative paths and your PHP files untouched. For example

1 1 * * * cd /home/username/public_html/&& php -f script.php

check this answer

also check this article, I will quote the relative part

Depending on the code in your PHP script, it may only run correctly when called from a specific directory. For example, if the script uses relative paths to include files, it will only run if it is called from the correct directory. The following command shows how to call a PHP script from a specific directory:

cd /home/username/public_html/; php -q script.php
Accountant م
  • 4,969
  • 2
  • 30
  • 49
  • 2
    This answer is the better. – Alexis Vandepitte Jan 10 '20 at 08:50
  • 1
    I had a WordPress installation on HostGator where this was really the only solution as the relative paths in included core files would trigger errors and could not be modified directly. – spyke01 May 02 '20 at 13:15
  • Much more better and cleaner solution. – amone Jan 16 '21 at 08:34
  • This should definitely be the accepted answer (but I understand it came almost a decade after the first answer). This is a much more sustainable solution. – Mike Apr 13 '21 at 16:00
3

An alternative to the solutions which recommend absolute path specification is using a chdir in your script. That way, your relative paths will work as expected.

For example, to change to the directory of the script:

$curr_dir = dirname(__FILE__);
chdir($curr_dir);

To change to the parent directory of the script:

$curr_dir = dirname(__FILE__);
chdir($curr_dir . "/..");

And so forth.

Scott C Wilson
  • 16,711
  • 9
  • 54
  • 76
0

If the relative path doesn't work, then it means that the current directory set when the cron tasks are running is not /home/username123/public_html. In such cases, you can only use an absolute path.

kiamlaluno
  • 24,790
  • 16
  • 70
  • 85
0

It sounds as simple as just some script you are running is setting the include_path and you are including that script. use phpinfo() to check the include_path global vs local setting.

MANCHUCK
  • 2,269
  • 1
  • 15
  • 21