Asked  2 Years ago    Answers:  5   Viewed   198 times

If a PHP script is run as a cron script, the includes often fail if relative paths are used. For example, if you have

require_once('foo.php');

the file foo.php will be found when run on the command line, but not when run from a cron script.

A typical workaround for this is to first chdir to the working directory, or use absolute paths. I would like to know, however, what is different between cron and shell that causes this behavior. Why does it fail when using relative paths in a cron script?

 Answers

3

The working directory of the script may be different when run from a cron. Additionaly, there was some confusion about PHPs require() and include(), which caused confusion about the working directory really being the problem:

include('foo.php') // searches for foo.php in the same directory as the current script
include('./foo.php') // searches for foo.php in the current working directory
include('foo/bar.php') // searches for foo/bar.php, relative to the directory of the current script
include('../bar.php') // searches for bar.php, in the parent directory of the current working directory
Thursday, August 4, 2022
4

I have a Debian 10 VM on my local computer and have PHP 7.3.19 on it. After lots of time trying different approaches to the issue you're facing, on my side the issue turned out to relate to needing to include the full path to the echo program. I don't know if there is some other echo program on my machine that PHP was finding in a different path or something (and this might indirectly relate to what Michael was saying in the comment from earlier). At one point I was wondering if the backticks in the command were causing a problem with PHP, because the shell_exec() is evidently like the PHP backtick operator.

Here is what I did to get your createCronjob() to run successfully from the PHP side of things:

// ref: q21.php
function createCronjob($job)
{
    exec('/usr/bin/echo -e "`crontab -l`n'. $job .'" | crontab -', $output);
    return $output;
}

When I added the full path to the echo command, it began to work. Your echo path might be different, but it might be the same because we should be using similar systems.

I found out the echo path by using this command:

which echo

And it returned this location:

/usr/bin/echo

Also, for future reference, I don't know if this is a case where using the escapeshellcmd() might be a good idea in the future? I'm not very familiar with it, so I'm not sure if this is a situation where you would want to include it somewhere on your shell command (and it might make the command not run as intended anyway), but wanted to mention it!

Thursday, September 22, 2022
3

I had a similar challenge and created a single file that defines constants for all the relevant paths that I want to be able to call as-needed. I include this file in all my pages (I define the $urlRoot so that this will work in all environments and is moveable do different domains, etc):

File: pathData.php (added MENUDIR for your example):

$baseDir = dirname(__DIR__) . '/';
$rootUrl = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';
define('ROOTURL', $rootUrl);
define('BASEDIR', $baseDir);
define('INCLUDES', $baseDir . 'includes/');
define('INCLUDESURL', ROOTURL . 'includes/');
define('JQUERYURL', ROOTURL . 'includes/jquery/');
define('MENUDIR', ROOTURL . 'views/general/');

Then in each file, I include that file with an include that includes the relative directory path. For example:

include("pathData.php");
or
include("../pathData.php");
or
include("../../pathData.php); 
etc.

So in your case you could (depending on where your pathData file is):

include("../pathData.php");
include(MENUDIR . "navbar.php");
etc...
Saturday, August 6, 2022
 
miguev
 
5

Took me about 5 hours of Google and trying different things to FINALLY find the answer!

#ifdef __APPLE__
#include "CoreFoundation/CoreFoundation.h"
#endif

// ----------------------------------------------------------------------------
// This makes relative paths work in C++ in Xcode by changing directory to the Resources folder inside the .app bundle
#ifdef __APPLE__    
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
    char path[PATH_MAX];
    if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
    {
        // error!
    }
    CFRelease(resourcesURL);

    chdir(path);
    std::cout << "Current Path: " << path << std::endl;
#endif
// ----------------------------------------------------------------------------

I've thrown some extra include guards because this makes it compile Apple only (I develop cross platform) and makes the code nicer.

I thank the other 2 guys for your answers, your help ultimately got me on the right track to find this answer so i've voted you both up. Thanks guys!!!!

Thursday, September 29, 2022
2

Cronjob is not something to create as Php process or script. Cron is a linux program that allows you to call a script at a regular interval.

You can see what is an crontab by entering in your linux machine as an admin user and type:

[email protected]:~# crontab -e

You will see something like

*/1 * * * * /usr/bin/php /var/www/somesite/public/cron.php

This means that each minute I am executing the cron.php.

Now, you may want to have different scripts executed at different times and want to pass this logic to php level instead of linux level. If this is the case you may want to call your cron script at the lowest time denominator (minute for example) and in the cron.php build some logic that will call at different times other scripts.

I use for example a Cronable interface:

interface Cronable {
    public function cron();
}

And each class that wants to be called by the cron.php has to implement this interface and the cron() function, which will specify what is the specific frequency of the call. The cron.php will get all this classes and will compare current time with that time and will decide to execute the call or not.

Thursday, September 8, 2022
 
dannyt
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 

Browse Other Code Languages