3

I've made a PHP framework. To start it, you do:

require 'framework.php';
framework_start(__DIR__);

I'm trying to eliminate the __DIR__ part, if at all possible. It's telling the framework what the "base dir" for the application is. I can't think of any way to determine the "__DIR__" for the file that calls framework_start(), from within framework_start().

I can't help but feel annoyed that it can't just be:

require 'framework.php';
framework_start();

... and then framework_start(); somehow figures out the __DIR__ value on its own. But if I just reference __DIR__ from the PHP file that contains framework_start(), it will obviously return the wrong dir path.

Is this possible at all? If so, how?

brombeer
  • 8,716
  • 5
  • 21
  • 27
  • Maybe this would help: https://stackoverflow.com/questions/10393145/get-filename-of-file-which-ran-php-include – Dharman May 30 '19 at 20:44
  • Not really... I see no solution on that page? But this, on the other hand, seems to actually solve it (but I'm not sure yet): https://stackoverflow.com/a/5670742/11555230 –  May 30 '19 at 20:46
  • I was thinking about this `pathinfo(debug_backtrace()[0]['file'])['dirname']` – Dharman May 30 '19 at 20:49
  • Does `framework.php` contain `framework_start()`? – brombeer May 30 '19 at 20:49
  • 1
    Hmm, yeah, it seems like there should be a way... If there is you could even put the framework_start() call in the framework.php file, so all you'd need is the require. – Stevish May 30 '19 at 20:50
  • https://stackoverflow.com/questions/139794/can-i-get-the-path-of-the-php-file-originally-called-within-an-included-file says you can use `$dir=dirname($_SERVER["SCRIPT_FILENAME"])`... – Stevish May 30 '19 at 20:52
  • What I linked to 7 minutes ago does NOT work! It screwed up my whole system because I was too happy and careless over finding the "solution"... –  May 30 '19 at 20:54
  • @Stevish That is only the top-most script and only if that variable is set. OP is asking for the direct parent file. – Dharman May 30 '19 at 20:54
  • kerbholz: Yes. Stevish: That will only work in WWW mode, unless I'm mistaken. –  May 30 '19 at 20:55
  • This is an excellent question. I'm going to sleep on it, but if I don't find the answer I'll be interested to find out if someone else does. – Stevish May 30 '19 at 20:57
  • Hm, are you sure `__DIR__` would _obviously return the wrong dir path_ when called from within `framework_start()`? Have you tried that? Since `framework.php` seems to be in the same folder as the file including it. – brombeer May 30 '19 at 21:00
  • What? No. They are in completely different dirs. That's the whole point. –  May 30 '19 at 21:12

1 Answers1

1

I would suggest the following. Define a constant at the top of framework.php file to be used in your framework instead of __DIR__:

$trace = debug_backtrace(false);
$levelsToGoUp = 0; // set to 1 if called from within the function 
if (array_key_exists($levelsToGoUp, $trace)) {
    define('PARENTFILE', dirname($trace[$levelsToGoUp]['file']));
} else {
    define('PARENTFILE', __DIR__);
}

If you called debug_backtrace() inside the function framework_start() you would need to look at the entry with key 1 in the array (the first is the function itself), which I would recommend.

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Although a bit confusing, this really helped me. I consider it the solution, even though (at least in my framework) also let the user (meaning me, for different projects) explicitly set the application base dir path, since it's not *always* the same as the file that "kickstarts" it. For example, I sometimes have the kickstart file in a subdir to the application dir, and for those situations, I send: __DIR__ . '/..' as an argument, and then it picks that instead of automatically determining it. However, now, with the help of your code snippet (which hopefully is stable), it normally requires no –  May 30 '19 at 22:07
  • argument. Thanks. (This stupid, over-engineered site has an ultra-low char limit for comments...) –  May 30 '19 at 22:09