9

(初步说明:这个问题似乎已经有很多变体,但它们似乎都关注物理 PHP 文件本身的文件系统位置,而不是事物的Web URL 位置,这就是我所追求的。)


介绍 1:

我有一个具有以下物理文件系统结构的小型“网站”:

variable.php
folder
  test.php

(换句话说,variable.php在顶层和test.php文件夹中folder。)

以下是文件内容:

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

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

介绍 2:

在本地开发这个“网站”时,它在这个地址上:

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

问题:

问题是,如果我放入http://localhost/~noob/test-website/folder/test.php浏览器,它会打印出/~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).

4

10 回答 10

4

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

于 2012-10-18T14:24:53.510 回答
3

Hopefully this will come close (all this should be in variables.php):

// folder containing the requested script
$requested = dirname($_SERVER['SCRIPT_FILENAME']);

// folder containing variables.php
$current = dirname(__FILE__);

// relative path from variables.php to the requested script
$relative = str_replace($current, '', $requested);

// remove relative path from end of script name
$pattern = '#' . preg_quote($relative) . '$#';
$basePath = preg_replace($pattern, '', dirname($_SERVER['SCRIPT_NAME']));

Note: This looks like it will work for your particular example, but this means that variables.php must always be in a folder either at, or a parent of, the DOCUMENT_ROOT, otherwise the relative path can't be determined using the above.

于 2012-10-14T23:09:03.123 回答
1

I'm not sure it's gonna solve your problem forever or not, however it works in your example:

$x = explode("/", $_SERVER['SCRIPT_NAME']);
echo $_SERVER['SERVER_NAME'] . '/' . $x[1] . '/';

If you like the output, you may customize it to fit your needs. :)

于 2012-10-15T11:22:09.910 回答
1

It's not entirely foolproof, but the solution used by Kurogo works in most cases.

https://github.com/modolabs/Kurogo-Mobile-Web/blob/release-1.5/lib/Kurogo.php#L797

It's basically comparing the REQUEST_URI and the DOCUMENT_ROOT, and keeps adding folders from the REQUEST_URI to the DOCUMENT_ROOT until it gets a match. Once it finds WEBROOT_DIR (which in your case would probably be a dirname(__FILE__) from the variables.php) by building up from DOCUMENT_ROOT, it saves the existing path as your $urlBase.

This only works for subfolders/symlinks, and doesn't handle things like apache aliasing, so it may not work for your case specifically, but it's at least part of the answer.

于 2012-10-23T16:18:01.583 回答
0

I worked in a project where it was necesary to read a directory with a lot of images, with folders within, and it was required to read all the files in a recursive way...

Function:

function ListIn($dir, $prefix = '') {
  $dir = rtrim($dir, '\\/');
  $result = array();

    foreach (scandir($dir) as $f) {

        if ($f !== '.' and $f !== '..') {

            if (is_dir("$dir/$f")) {
              $result = array_merge($result, ListIn("$dir/$f", "$prefix$f/"));
            } 
            else {
                $ext = substr($prefix.$f, strrpos($prefix.$f, '.') + 1);

                if(in_array($ext, array("jpg"))){
                    // echo $prefix.$f."<br>";
                    $result[] = $prefix.$f;
                }


            }

        }

    }

  return $result;
}

Way of use:

$path='images/mytest';

$images = (ListIn($path));

foreach($images as $image){
        $image=explode("/",$image);
        echo $image=$image[2];
}

As you can see, every single image becomes an array, and you can access to the first elements of that array, in order to extract the directory you want... In this case it was located at the second index of the array, depending on the deepness of your file structure...

I hope this can help you out!

于 2012-10-22T16:15:38.557 回答
0

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

You can hardcode paths, just make it relative to the homepage.

For example, http://localhost/~noob/test-website/ and http://example.com are the same thing. so only worry about things underneath that .

于 2012-10-24T15:42:13.677 回答
0

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

[HR][/HR]INTRO 1:

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

variable.phpfolder test.php(In other words, variable.php in the top-level, and test.php in the folder folder.) Here are the file contents:

[HR][/HR]INTRO 2:

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

http://localhost/~noob/test-website[HR][/HR]QUESTION:

The problem is that if I put

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

于 2012-10-25T05:15:22.263 回答
0

You can estimate the correct answer based on your knowledge of your specific folder and web structure, but that is far from a general solution. But I would recommend you to use a boostrap file that is the entry point for each "page". There you can setup you $basePath variable and other needed values.

Another thing you could do is inject the base path to your $_SERVER array from Apache (if that is what you are using. It would then be available to your entire application.

For a pointer on how to accomplish this you can look here.

Or have a config file containing the base path for a given server.

于 2012-10-25T09:23:55.890 回答
-1

I think, you're searching the docroot (form outside) - it can be found in $_SERVER['DOCUMENT_ROOT'] (in the filesystem) & compare with __DIR__ (or dirname(__FILE__) for earlier PHP)

于 2012-10-21T10:24:18.480 回答
-1

Use this function :-

#This function will return the current script name
function get_script_name()
{
    $uri_array = explode('/',$_SERVER['SCRIPT_NAME']);
    $script_name = end($uri_array);
     return $script_name;
}
#call The function
$script_name = get_script_name();
echo $script_name;
于 2012-10-23T11:19:16.487 回答