5

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

Community
  • 1
  • 1
genesis
  • 50,477
  • 20
  • 96
  • 125
  • be aware : $_SERVER['SERVER_NAME'] may not give mydomain.com depending on the configuration of the server. use $_SERVER['HTTP_HOST'] instead – EKanadily Feb 17 '17 at 07:31

7 Answers7

8

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.

grep
  • 3,986
  • 7
  • 45
  • 67
  • I can't but that absolute path because if you're doing open-source, you can't know what the url is, and in case you would need to include one header (which would like to include `css/default.css`) can't be used anymore in child folder – genesis Jun 28 '11 at 20:22
  • 1
    @genesis: Can you clarify what you mean? I found that sentence impossible to parse. – George Cummins Jun 28 '11 at 20:30
  • @genesis: It comes down to the fact that you cannot just easily "find" the location of a file dynamically unless you want to build up a function that recursively searches through directories and returns the path of the matched file, or if you want to escape to the shell and do a find. Your file structure should not change if you are building this project correctly. Thus, just use the suggested method of dynamically adding the server name to the uri so it works between domains/hosts – grep Jun 28 '11 at 20:36
  • @George: Look, you do have open-source software, self-written. User can add it to /subdir/ instead of to / - right? Now, I have seo-friendly urls. So url looks like /subdir/any/url/ and I need to get css file from /subdir/css/ - so I need to DETECT /subdir/ as app path. So in I could use `` – genesis Jun 28 '11 at 20:47
  • 1
    $genesis: you are looking down a unnecessarily complicated path. Set up a definition, or parse a .ini file which holds this path and then define it so it can be easily changed through the setting.ini file for example. If you really want to detect the path, I would recommend escaping to the shell, doing a find, and have it return the path . – grep Jun 28 '11 at 20:52
  • $_SERVER['SERVER_NAME'] may not give mydomain.com depending on the configuration of the server. use $_SERVER['HTTP_HOST'] instead – EKanadily Feb 17 '17 at 07:30
3
$url = "http" . ($_SERVER['HTTPS'] ? 's' : '') . "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
2

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
George Cummins
  • 28,485
  • 8
  • 71
  • 90
  • I want to call that page from another page, for example index.php. But thanks a lot :) – genesis Jun 28 '11 at 19:19
  • @genesis: My example was simply designed to show you the available data. You don't need to echo it; you can redirect to another page using header("Location:...") or use it in any other way you desire. – George Cummins Jun 28 '11 at 20:03
  • George I'm not new in PHP and I know that these superglobals exist. But I HAVE TO BUILD ABSOLUTE PATH TO APPLICATION DIRECTORY for later use – genesis Jun 29 '11 at 05:03
  • 1
    @genesis: Yelling at people giving you free advice is a good way not to get free advice. Furthermore, if your question was unclear, the fault can hardly lie with the answerer. I hope it all works out for you. – George Cummins Jun 29 '11 at 12:45
  • Sorry @George, yesterday I edited my question and someone edited it and deleted my edit. Can you read it now please? "These examples will return after url("ajax.php"); function is called" – genesis Jun 29 '11 at 14:27
  • $_SERVER['SERVER_NAME'] may not give mydomain.com depending on the configuration of the server. use $_SERVER['HTTP_HOST'] instead – EKanadily Feb 17 '17 at 07:31
1

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
  • Did you try it? Your first example? It does return /downloads/games/freegame_222/ajax.php ... I need /downloads/games/freegame_222/ or http://mydomain.com/downloads/games/freegame_222/ – genesis Jun 29 '11 at 05:01
  • 1
    I think you need to edit your OP. That's not what you specified in your question. –  Jun 29 '11 at 11:56
  • `Result will be: http://mydomain.com/downloads/games/freegame_222/ajax.php or /downloads/games/freegame_222/ajax.php ` – genesis Jun 29 '11 at 14:08
  • You asked for `/downloads/games/freegame_222/ajax.php`, and I provided code that gave you `/downloads/games/freegame_222/ajax.php`, but you are saying that I didn't give you what you wanted. Perhaps you can understand my confusion. –  Aug 02 '12 at 18:25
0

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.

bruno.braga
  • 1,001
  • 12
  • 21
0

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:

  1. Absolute path to install directory (e.g. /var/www/myserver/mysubdir/) which will be required for include files;
  2. 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/)
  3. 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 a config.php from the top directory to know about things like database connection strings, global app parameters, etc.
  4. 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 at http://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?

Gwyneth Llewelyn
  • 796
  • 1
  • 11
  • 27
0

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;
}
Faaiq
  • 391
  • 4
  • 5