Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling $_SERVER['SCRIPT_NAME'] from files deeper in the hierarchy

Tags:

php

(Preliminary note: There are seemingly many variants of this question already here, but they all seem to focus on the filesystem location of the physical PHP files themselves, not the web URL location of things, which is what I'm after.)


INTRO 1:

I have a small "website" with the following physical filesystem structure:

variable.php
folder
  test.php

(In other words, variable.php in the top-level, and test.php in the folder folder.)

Here are the file contents:

<?php
//variable.php
$basePath = dirname($_SERVER['SCRIPT_NAME']);
?>

<?php
//test.php
include("../variables.php");
echo $basePath;
?>

INTRO 2:

When developing this "website" locally, it is on this address:

http://localhost/~noob/test-website

QUESTION:

The problem is that if I put http://localhost/~noob/test-website/folder/test.php into my browser, it prints out /~noob/test-website/folder/.

I want it to print out /~noob/test-website (the "web location" of variable.php). In other words, I want to have global access from all files, even ones deeper in the filesystem hierarchy, to /~noob/test-website. How do I accomplish this?

I obviously do not want to hardcode this path in. The reason is that when I upload it onto a production server, the location changes to something more sane like http://example.com/ (and I don't want to have to modify this hardcoded path after uploading to the server, hence this question of course).

like image 970
NoobOverflow Avatar asked Oct 14 '12 22:10

NoobOverflow


1 Answers

The problem here is, that your webserver (and thus PHP) does not know that your testing root directory is being served out of a subdirectory, and in fact neither of them care.

The obvious solution would be to provide a configuraiton script on each server, that has the hardcoded relative root in it. As you already stated, you don't want to do this. (It's not actually a bad thing to provide server-specific configuration files, lots of people do far more absurd things)

In order to get around this fact, a solution will have to hinge on the reference points that are available to it for a specific request. Those reference points are:

  • The filesystem location of variables.php
  • The filesystem location of the script being requested.
  • The filesystem location that is the root that pages are served from

(I know you've emphasised not filesystem - keep reading, we use these to get your value)

With these values, there will be an overlap in the directory structure. This is the value you are after.

Example:

  • Your test site is at: http://localhost/c/
  • Request: http://localhost/c/d/myscript.php
  • variables.php is at: /a/b/c/variables.php
  • myscript.php is at: /c/d/myscript.php includes ../variables.php

As you can see the paths overlap by the /c/ directory.

In your variables.php you can use the following code to calculate that overlap.

$fsRoot = __DIR__; // dirname(__FILE__) for PHP < 5.3 (and shame on you!)
$webRoot = str_replace($_SERVER['PHP_SELF'], '', $_SERVER['SCRIPT_FILENAME']);
$urlRoot = str_replace($webRoot, '', $fsRoot);

You should never rely on DOCUMENT_ROOT it can very easily be incorrect, so we're calculating it ourself ($webRoot variable).

This takes the filesystem directory of variables.php which is in your site root, and removes the the filesystem directory that is the base that pages are served from. What remains is everything that was between the actual web root, and your subdirectory web root.

In myscript.php you can do the following.

print $urlRoot . '/filename.js';

The output from the example would be /c/filename.js

like image 171
Leigh Avatar answered Nov 07 '22 17:11

Leigh