Get base directory of current script - php

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

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

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/

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

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/

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

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

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

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;

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"

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;

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/

Related

Extract specific part from URL

I have to extract a specific part of an URL.
Example
original URLs
http://www.example.com/PARTiNEED/some/other/stuff
http://www.example.com/PARTiNEED
in case 1 I need to extract
/PARTiNEED/
and in case 2 I need to extract the same part but add an additional "/" at the end
/PARTiNEED/
What I've got right now is this
$tempURL = 'http://'. $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$tempURL = explode('/', $tempURL);
$tempURL = "/" . $tempURL[3] . "/";
is there a more convenient way to do this or is this solution fine?
It's normally a good idea to use PHP's built in functions for things like this where possible. In this case, the parse_url method is designed for parsing URLs.
In your case:
// Extract the path from the URL
$path = parse_url($url, PHP_URL_PATH);
// Separate by forward slashes
$parts = explode('/', $path);
// The part you want is index 1 - the first is an empty string
$result = "/{$parts[1]}/";
You don't need this part:
'http://'. $_SERVER['SERVER_NAME']
you can just do:
$tempURL = explode('/', $_SERVER['REQUEST_URI']);
$tempURL = "/" . $tempURL[1] . "/";
Edited index from 0 to 1 as commented.
Maybe regex suits your needs better?
$tempURL = "http://www.example.com/PARTiNEED/some/other/stuff"; // or $tempURL = "http://www.example.com/PARTiNEED
$pattern = '#(?<=\.com)(.+?)(?=/|$)#';
preg_match($pattern, $tempURL, $match);
$result = $match[0] . "/";
Here this should solve your problem
// check if the var $_SERVER['REQUEST_URI'] is set
if(isset($_SERVER['REQUEST_URI'])) {
// explode by /
$tempURL = explode('/', $_SERVER['REQUEST_URI']);
// what you need in in the array $tempURL;
$WhatUNeed = $tempURL[1];
} else {
$WhatUNeed = '/';
}
Dont worry about the trailing slash, that can be added anytime in your code.
$WhatUNeed = $tempURL[1].'/';
This will give you proper idea about your requirment.
<?php
$url_array = parse_url("http://www.example.com/PARTiNEED/some/other/stuff");
$path = $url_array['path'];
var_dump($path);
?>
now you can use string explode function to get your job done.

Php url parsing and editing

I searched "the whole" stackoverflow but didn't find a decent answer that works for me. I need to change the host of a url in php.
This url: http://example123.com/query?t=de&p=9372&pl=bb02799a&cat=&sz=400x320&scdid=e7311763324c781cff2d3bc55b2d83327aba111f2db79d0682860162c8a13c24&rnd=29137126
To This: http://example456.com/test?t=de&p=9372&pl=bb02799a&cat=&sz=400x320&scdid=e7311763324c781cff2d3bc55b2d83327aba111f2db79d0682860162c8a13c24&rnd=29137126
I only need to change the domain and the path or file, so far I've got this:
$originalurl = http://example123.com/query?t=de&p=9372&pl=bb02799a&cat=&sz=400....
$parts = parse_url($originalurl);
$parts['host'] = $_SERVER['HTTP_HOST'];
$parts['path'] = '/test';
$modifiedurl = http_build_query($parts);
print_r(urldecode($modifiedurl));
but it echos
scheme=http&host=localhost&path=/test&query=t=de&p=9372&pl=bb02799a&cat=&sz=400...
Please I don't want to use some strpos or something like that as I need it to be variable.
Thanks ;)
$url = 'http://example123.com/query?t=de&p=9372&pl=bb02799a&cat=&sz=400x320&scdid=e7311763324c781cff2d3bc55b2d83327aba111f2db79d0682860162c8a13c24&rnd=29137126';
$query = parse_url($url)['query'];
$newUrl = 'http://www.younewdomain.com/path?' . $query;
You'll have to do some concatenating manually. This works:
$originalurl = "http://example123.com/query?t=de&p=9372";
$parts = parse_url($originalurl);
$new_path = '/test';
$modifiedurl = $parts['scheme'] . "://" . $_SERVER['HTTP_HOST'] . $new_path . (isset($parts['query']) ? "?".$parts['query']:"");
print_r($modifiedurl);
Came up with a different approach:
$url = "http://example123.com/query?t=de&p=9372&pl=bb02799a&cat=&sz=400x320&scdid=e7311763324c781cff2d3bc55b2d83327aba111f2db79d0682860162c8a13c24&rnd=29137126";
$new_host = "http://newhost.com/blab";
//explode at ? so you get the query
$split = explode("?",$url,2);
//build new url
$new_url = $new_host."?".$split[1];
//finish
echo $new_url;
The reverse function of parse_url() should be http_build_url(), have you tried with it?

dirname($_SERVER["PHP_SELF"]) how to return bar correctly?

$path = (#$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
$path .=$_SERVER["SERVER_NAME"]. dirname($_SERVER["PHP_SELF"]);
I have this and this is what happens if I make a echo
echo $path
http:://localhost/folder
and without folder
http:://localhost/
if there is a folder not return my bar if I attached a bar as well the result without folder so
$path .=$_SERVER["SERVER_NAME"]. dirname($_SERVER["PHP_SELF"])."/";
echo $path
http:://localhost/folder
http:://localhost//
any idea better or more optimal to get what I want?
to give me a single bar in the two cases
If I understand the question correctly, by bar you actually mean / or the forward slash character, and that when the dirname() returns nothing, you end up with // but would like only a single /.
If this is the case, then the following should satisfy what you are looking for.
$path = (#$_SERVER["HTTPS"] == "on") ? "https://" : "http://" . $_SERVER["SERVER_NAME"] . '/' . trim(dirname($_SERVER["PHP_SELF"]),'/');
You can use rtrim($path, '/') to trim any / from back of url.

How to print current URL path?

I want to print out the current URL path, but my code doesn't work propperly.
I use this in my file.php
echo "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
When i open the url http://sub.mydomain.com/file.php it seems to work fine, and it prints "http://sub.mydomain.com/file.php"
But if i remove the .php extension so the url will be http://sub.mydomain.com/file instead, it prints "http://sub.mydomain.com/sub/file.php" which is wrong.
It prints the subdomain twice, and I don't know why?
In my .htaccess file, I have a rewrite that makes it possible to removes .php extensions.
Anyone who can/want to help me please? :)
You need $_SERVER['REQUEST_URI'] instead of $_SERVER['SCRIPT_NAME'], cos $_SERVER['SCRIPT_NAME'] will always give you the file which is working at the moment.
From manual:
SCRIPT_NAME: Contains the current script's path. This is useful for pages which need to point to themselves. The __FILE__ constant contains the full path and filename of the current (i.e. included) file. .
I suppose this helps you getting current URL fully.
echo 'http://'. $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
Notice: DO NOT RELY ON CLIENT'S HTTP_HOST, USE SERVER_NAME INSTEAD! SEE: What is the difference between HTTP_HOST and SERVER_NAME in PHP?
Security Warning
You need to filter (sanitize) $_SERVER['REQUEST_URI'] if you use it in anywhere (to print or store in database), cos it's not safe.
// ie: this could be harmfull
/user?id=123%00%27<script...
Hence, always filter user inputs before using them. At least use htmlspecialchars, htmlentities, strip_tags etc..
Or something like this;
function get_current_url($strip = true) {
static $filter, $scheme, $host, $port;
if ($filter == null) {
$filter = function($input) use($strip) {
$input = trim($input);
if ($input == '/') {
return $input;
}
// add more chars if needed
$input = str_ireplace(["\0", '%00', "\x0a", '%0a', "\x1a", '%1a'], '',
rawurldecode($input));
// remove markup stuff
if ($strip) {
$input = strip_tags($input);
}
// or any encoding you use instead of utf-8
$input = htmlspecialchars($input, ENT_QUOTES, 'utf-8');
return $input;
};
$scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME']
: ('http'. (($_SERVER['SERVER_PORT'] == '443') ? 's' : ''));
$host = $_SERVER['SERVER_NAME'];
$port = ($_SERVER['SERVER_PORT'] != '80' && $scheme != 'https')
? (':'. $_SERVER['SERVER_PORT']) : '';
}
}
return sprintf('%s://%s%s%s', $scheme, $host, $port, $filter($_SERVER['REQUEST_URI']));
}
$main_folder = str_replace('\\','/',dirname(__FILE__) );
$document_root = str_replace('\\','/',$_SERVER['DOCUMENT_ROOT'] );
$main_folder = str_replace( $document_root, '', $main_folder);
if( $main_folder ) {
$current_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME']. '/' . ltrim( $main_folder, '/' ) . '/';
} else {
$current_url = $_SERVER['REQUEST_SCHEME'].'://'.rtrim( $_SERVER['SERVER_NAME'], '/'). '/';
}

How can I get the current web directory from the URL?

If I have a URL that is http://www.example.com/sites/dir/index.html, I would want to extract the word "sites". I know I have to use regular expressions but for some reason my knowledge of them is not working on PHP.
I am trying to use :
$URL = $_SERVER["REQUEST_URI"];
preg_match("%^/(.*)/%", $URL, $matches);
But I must be doing something wrong. I would also like it to have a catch function where if it is at the main site, www.example.com then it would do the word "MAIN"
Edit: sorry, I've known about dirname...It gives the full directory path. I only want the first directory.... So if its www.example.com/1/2/3/4/5/index.html then it returns just 1, not /1/2/3/4/5/
Use the dirname function like this:
$dir = dirname($_SERVER['PHP_SELF']);
$dirs = explode('/', $dir);
echo $dirs[0]; // get first dir
Use parse_url to get the path from $_SERVER['REQUEST_URI'] and then you could get the path segments with explode:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = explode('/', substr($_SERVER['REQUEST_URI_PATH'], 1));
echo $segments[1];
The dirname function should get you what you need
http://us3.php.net/manual/en/function.dirname.php
<?php
$URL = dirname($_SERVER["REQUEST_URI"]);
?>
Just wanted to recommend additionally to check for a prefixed "/" or "\"
and to use DIRECTORY_SEPARATOR :
$testPath = dirname(__FILE__);
$_testPath = (substr($testPath,0,1)==DIRECTORY_SEPARATOR) ? substr($testPath,1):$testPath;
$firstDirectory = reset( explode(DIRECTORY_SEPARATOR, dirname($_testPath)) );
echo $firstDirectory;
A simple and robust way is:
$currentWebDir = substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']));
If you are worried about DIRECTORY_SEPARATORS, you could also do:
$currentWebDir = str_replace('\\', '/', substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT'])));
Also be aware of mod_rewrite issues mentioned by FrancescoMM

Categories