Home » Php » php – Get base directory of current script

php – Get base directory of current script

Posted by: admin April 23, 2020 Leave a comment

Questions:

This is the url of my script: localhost/do/index.php

I want a variable or a function that returns localhost/do (something like $_SERVER['SERVER_NAME'].'/do')

How to&Answers:

Try:

$url = $_SERVER['REQUEST_URI']; //returns the current URL
$parts = explode('/',$url);
print_r($parts);

EDIT:

$url = $_SERVER['REQUEST_URI']; //returns the current URL
$parts = explode('/',$url);
$dir = $_SERVER['SERVER_NAME'];
for ($i = 0; $i < count($parts) - 1; $i++) {
 $dir .= $parts[$i] . "/";
}
echo $dir;

This should return localhost/do/

Answer:

$_SERVER['SERVER_NAME'] . dirname($_SERVER['REQUEST_URI']);

Answer:

php has many functions for string parsing which can be done with simple one-line snippets
dirname() (which you asked for) and parse_url() (which you need) are among them

<?php

echo "Request uri is: ".$_SERVER['REQUEST_URI'];
echo "<br>";

$curdir = dirname($_SERVER['REQUEST_URI'])."/";

echo "Current dir is: ".$curdir;
echo "<br>";

address bar in browser is

http://localhost/do/index.php

output is

Request uri is: /do/index.php
Current dir is: /do/

Answer:

When I was implementing some of these answers I hit a few problems as I’m using IIS and I also wanted a fully qualified URL with the protocol as well. I used PHP_SELF instead of REQUEST_URI as dirname('/do/') gives '/' (or '\') in Windows, when you want '/do/' to be returned.

if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') {
    $protocol = 'http://';
} else {
    $protocol = 'https://';
}
$base_url = $protocol . $_SERVER['SERVER_NAME'] . dirname($_SERVER['PHP_SELF']);

Answer:

I suggest not to use dirname(). I had several issues with multiple slashes and unexpected results at all. That was the reason why I created currentdir():

function currentdir($url) {
    // note: anything without a scheme ("example.com", "example.com:80/", etc.) is a folder
    // remove query (protection against "?url=http://example.com/")
    if ($first_query = strpos($url, '?')) $url = substr($url, 0, $first_query);
    // remove fragment (protection against "#http://example.com/")
    if ($first_fragment = strpos($url, '#')) $url = substr($url, 0, $first_fragment);
    // folder only
    $last_slash = strrpos($url, '/');
    if (!$last_slash) {
        return '/';
    }
    // add ending slash to "http://example.com"
    if (($first_colon = strpos($url, '://')) !== false && $first_colon + 2 == $last_slash) {
        return $url . '/';
    }
    return substr($url, 0, $last_slash + 1);
}

Why you should not use dirname()

Assume you have image.jpg located in images/ and you have the following code:

<img src="<?php echo $url; ?>../image.jpg" />

Now assume that $url could contain different values:

  • http://example.com/index.php
  • http://example.com/images/
  • http://example.com/images//
  • http://example.com/
  • etc.

Whatever it contains, we need the current directory to produce a working deeplink. You try dirname() and face the following problems:

1.) Different results for files and directories

File
dirname('http://example.com/images/index.php') returns http://example.com/images

Directory
dirname('http://example.com/images/') returns http://example.com

But no problem. We could cover this by a trick:
dirname('http://example.com/images/' . '&') . '/'returns http://example.com/images/

Now dirname() returns in both cases the needed current directory. But we will have other problems:

2.) Some multiple slashes will be removed
dirname('http://example.com//images//index.php') returns http://example.com//images

Of course this URL is not well formed, but multiple slashes happen and we need to act like browsers as webmasters use them to verify their output. And maybe you wonder, but the first three images of the following example are all loaded.

<img src="http://example.com/images//../image.jpg" />
<img src="http://example.com/images//image.jpg" />
<img src="http://example.com/images/image.jpg" />
<img src="http://example.com/images/../image.jpg" />

Thats the reason why you should keep multiple slashes. Because dirname() removes only some multiple slashes I opened a bug ticket.

3.) Root URL does not return root directory
dirname('http://example.com') returns http:
dirname('http://example.com/') returns http:

4.) Root directory returns relative path
dirname('foo/bar') returns .

I would expect /.

5.) Wrong encoded URLs
dirname('foo/bar?url=http://example.com') returns foo/bar?url=http:

All test results:
http://www.programmierer-forum.de/aktuelles-verzeichnis-alternative-zu-dirname-t350590.htm#4329444

Answer:

If you want to include the server name, as I understood, then the following code snippets should do what you are asking for:

$result = $_SERVER['SERVER_NAME'] . dirname(__FILE__);

$result = $_SERVER['SERVER_NAME'] . __DIR__; // PHP 5.3

$result = $_SERVER['SERVER_NAME'] . '/' . dirname($_SERVER['REQUEST_URI']);

Answer:

dirname will give you the directory portion of a file path. For example:

echo dirname('/path/to/file.txt');  // Outputs "/path/to"

Getting the URL of the current script is a little trickier, but $_SERVER['REQUEST_URI'] will return you the portion after the domain name (i.e. it would give you “/do/index.php”).

Answer:

the best way is to use the explode/implode function (built-in PHP) like so

$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$parts = explode('/',$actual_link);
$parts[count($parts) - 1] = "";
$actual_link = implode('/',$parts);
echo $actual_link;

Answer:

My Suggestion:

const DELIMITER_URL = '/';
$urlTop = explode(DELIMITER_URL, trim(input_filter(INPUT_SERVER,'REQUEST_URI'), DELIMITER_URL))[0]

Test:

const DELIMITER_URL = '/';
$testURL = "/top-dir";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

$testURL = "/top-dir/";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

$testURL = "/top-dir/test";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

$testURL = "/top-dir/test/";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

$testURL = "/top-dir/test/this.html";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

$testURL = "/top-dir/test.html";
var_dump(explode(DELIMITER_URL, trim($testURL, DELIMITER_URL))[0]);

Test Output:

string(7) "top-dir"
string(7) "top-dir"
string(7) "top-dir"
string(7) "top-dir"
string(7) "top-dir"
string(7) "top-dir"

Answer:

A shorter (and correct) solution that keeps trailing slash:

$url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$url_dir = preg_replace('/[^\/]+\.php(\?.*)?$/i', '', $url);
echo $url_dir;

Answer:

My Contribution
Tested and worked

/**
* Get Directory URL
*/
function get_directory_url($file = null) {
    $protocolizedURL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $trailingslashURL= preg_replace('/[^\/]+\.php(\?.*)?$/i', '', $protocolizedURL);
    return $trailingslashURL.str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}

USAGE
Example 1:
<?php echo get_directory_ur('images/monkey.png'); ?>
This will return http://localhost/go/images/monkey.png

Example 2:
<?php echo get_directory_ur(); ?>
This will return http://localhost/go/