/**
* Check if file is in public directory. This will not work if running via CLI.
*
* @param bool $checkCallerScript Set to `true` to check for caller script using trace.
* @return bool Return `true` if it is in public directory, return `false` for otherwise.
*/
function isInPublicDir(bool $checkCallerScript = true): bool
{
if (!isset($_SERVER['HTTP_HOST']) || !isset($_SERVER['REMOTE_ADDR'])) {
// if no HTTP or ip address from user.
return false;
}
if (!isset($_SERVER['DOCUMENT_ROOT']) || empty($_SERVER['DOCUMENT_ROOT'])) {
// if no document root. run from CLI don't have this value.
// see https://www.php.net/manual/en/reserved.variables.server.php for more details.
return false;
}
$docRoot = str_replace(['\\', '/', DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, $_SERVER['DOCUMENT_ROOT']);
if (true === $checkCallerScript) {
$traces = debug_backtrace();
if (is_array($traces)) {
foreach ($traces as $trace) {
$callerFile = str_replace(['\\', '/', DIRECTORY_SEPARATOR], DIRECTORY_SEPARATOR, ($trace['file'] ?? null));
if (!isset($callerFile) || stripos($callerFile, $docRoot) === false) {
return false;
}
}
unset($callerFile, $trace);
}
unset($traces);
}
unset($docRoot);
return true;
}
The function above will not work if running via CLI or something that don't have DOCUMENT_ROOT
value.
Read more about $_SERVER
If I have files like this...
/var/www/public_html/run.php
/var/www/test.php
/var/www/functions.php <- the function above is in this file.
And public directory is /var/www/public_html
require dirname(__DIR__) . '/functions.php';
var_dump(isInPublicDir());// expect true
var_dump(isInPublicDir(false));// expect true
require dirname(__DIR__) . '/test.php';
run.php contents.
.
<?php
echo 'hello from ' . __FILE__ . '<br>' . PHP_EOL;
var_dump(isInPublicDir());// expect **false**
var_dump(isInPublicDir(false));// expect true
test.php contents.