cdxf
cdxf

Reputation: 5648

Get base directory of current script

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')

Upvotes: 36

Views: 102648

Answers (11)

Kolawole Emmanuel Izzy
Kolawole Emmanuel Izzy

Reputation: 1052

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/

Upvotes: 0

Ivan Castellanos
Ivan Castellanos

Reputation: 8243

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;

Upvotes: 0

tylersDisplayName
tylersDisplayName

Reputation: 1643

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"

Upvotes: 0

Med Abida
Med Abida

Reputation: 1222

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;

Upvotes: 1

mgutt
mgutt

Reputation: 6177

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

Upvotes: 9

www333
www333

Reputation: 396

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

Upvotes: 36

icc97
icc97

Reputation: 12793

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']);

Upvotes: 8

Your Common Sense
Your Common Sense

Reputation: 157870

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/

Upvotes: 8

Calvin
Calvin

Reputation: 8765

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/

Upvotes: 34

avpaderno
avpaderno

Reputation: 29679

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']);

Upvotes: 2

hbw
hbw

Reputation: 15750

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").

Upvotes: 1

Related Questions