This is almost same question as this
I need to get ABSOLUTE url to my script. For example, I have this structure
http://mydomain.com/downloads/games/freegame_222/ajax.php
My application root would be in freegame_222/
but, how can I "build" absolute, not relative path to ajax.php? Result will be
http://mydomain开发者_JS百科.com/downloads/games/freegame_222/ajax.php
or
/downloads/games/freegame_222/ajax.php
but not:
ajax.php
These examples will return after url("ajax.php");
is called
Is there a native function in PHP for it? If no, does anybody know about any custom one?
EDIT:
I want to call that page from another page, for example index.php
Similar to George Cummins' answer, simply do something like such:
$path = $_SERVER['SERVER_NAME'] . '/' . $_SERVER['REQUEST_URI'];
This should give you the complete path. Now if you want to get this from another page, what reason is there to have it generate the url dynamically? Why can't you just use the absolute path, or if anything, $_SERVER['SERVER_NAME']
+ rest of path so it works between domains/hosts.
$url = "http" . ($_SERVER['HTTPS'] ? 's' : '') . "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
This data is contained in the $_SERVER superglobal
echo $_SERVER['REQUEST_URI']; // Output: /downloads/games/freegame_222/ajax.php
echo $_SERVER['SERVER_NAME']; // Output: mydomain.com
The parse_url() function might do what you are looking for:
$url = 'http://mydomain.com/downloads/games/freegame_222/ajax.php';
$path = parse_url($url, PHP_URL_PATH);
Here's a more complete example from the manual page:
<?php
$url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>
The above example will output:
Array ( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor ) /path
Not pertinent to the question, however it is worth mentioning that HTTP/HTTPS can be omitted as a result of port forwarding or reverse proxy. You can do something like this to overcome this:
function getBaseURL() {
$isHttps = ((array_key_exists('HTTPS', $_SERVER)
&& $_SERVER['HTTPS']) ||
(array_key_exists('HTTP_X_FORWARDED_PROTO', $_SERVER)
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
);
return 'http' . ($isHttps ? 's' : '') .'://' . $_SERVER['SERVER_NAME'];
}
Note: This is particularly useful on Amazon EC2 deployed under ELB with HTTPS.
There has been some incivility here which prevented @genesis to get what he needs.
Because I pretty much "need" the same, here is my (reformulated) question (and a potential answer).
Assumptions: Application can be installed pretty much anywhere, since it will be downloaded by someone from an open-source repository. So there is the need to automatically determine:
- Absolute path to install directory (e.g.
/var/www/myserver/mysubdir/
) which will be required for include files; - Absolute URL for that very same directory, for instance, for menu navigation and calling .php files from anywhere within the application (e.g.
http://myserver.tld/mysubdir/
) - There might be an unknown depth limit to those subdirectories: for example, under the main directory, there might be
/css
,/js
but also things like/admin/plugins/js
which, however, might need to retrieve aconfig.php
from the top directory to know about things like database connection strings, global app parameters, etc. - The application itself might use a few levels by itself; the user who installs the application might also do the same (e.g.
/var/www/myserver
is where the virtual host is pointing to, but the end-user wants the application to be under/var/www/myserver/yes/I/really/want/it/this/deep
and expects the application to be fully functional athttp://myserver.tld/yes/I/really/want/it/this/deep
I have taken a look at how WordPress does this. Basically, WordPress requires that the URL pointing to the directory structure is hard-coded by the user (other applications do not). Then it extracts the directory path (for file inclusion) with
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
This looks rather neat, but, in reality, the problem is that if you're "deep" in the directory hierarchy, it might be impossible to include the file that defines ABSPATH. What WordPress is constantly doing is to call those two lines and include the required configuration file after it made sure that it got a valid ABSPATH.
But other software seem to be much better organized. They automagically extract the correct URL to the directory where the webserver is pointing to; and they even-more-magically are able to find where all the include files are, no matter how deep in the subdirectory structure they're located.
The best I could do is to emulate WordPress: 'force' the user to write the URL in the configuration file, and, on all levels and sublevels, start pretty much every file with
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
and attempt to include the global configuration file by guesswork (e.g. test if it's at the same level, one level up, two levels up, and so forth...).
This is extremely messy, but it seems that's what some gold-class applications (like WordPress) are doing. Others seems so much more organized. How do they do it? I have no idea.
@genesis, is this what you had in mind?
Below Function can be used to get proper absolute url.
function make_abs_url() {
$path = $_SERVER['SERVER_NAME'] . '/' . $_SERVER['REQUEST_URI'];
$path_arr = explode("/", $path);
$new_arr = array();
for($i = 0; $i < count($path_arr); ++$i) {
if(trim($path_arr[$i]) != "") {
$new_arr[] = $path_arr[$i];
}
}
$element = array_pop ( $new_arr);
$abs_path = implode("/", $new_arr);
if(substr($abs_path, 0, 4) != "http") {
$abs_path = "http://" . $abs_path;
}
return $abs_path;
}
精彩评论