绝对与相对路径

时间:2011-12-02 12:47:22

标签: php relative-path absolute-path

如果我使用绝对路径,我无法将整个目录移动到新位置。 如果我使用相对路径,我无法将单个文件移动到新位置。

这里有什么解决方案?你是否设置了一个包含根路径的配置文件并从那里开始?或者你有一个规则:永远不要移动文件?

我在一些项目中看到人们使用dirname( FILE )。有什么意义,我的意思是,为什么不简单地把它留下来,因为dirname无论如何都是相对的(取决于文件所在的位置)?

5 个答案:

答案 0 :(得分:15)

你应该使用一个配置文件,它将包含在每个文件的第一行,例如你的应用程序看起来像这样

root / App / Plugins

在根目录中:app-config.php

if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

现在,假设你必须包含一个插件文件,所以

在插件目录中:my-plugin.php

require_once '../../app-config.php';

现在此行下方的所有内容都可以使用ABSPATH

示例是否要加载图像

<img src='".ABSPATH."Public/images/demo.png' alt=''/>

现在,如果您的应用程序旨在自动加载某些文件,例如

,则更简单
plugin-widget-1.php

这样,my-plugin.php文件加载的此文件或任何其他文件中的所有内容都可以使用ABSPATH,而不是每次app-config.php文件都包含。

考虑到这一点,您可以将所需的所有短片放入app-config.php示例

define('UPLOAD_PATH', ABSPATH. 'Public/uploads/');
define('IMAGES_PATH', ABSPATH. 'Public/images/');
define('HELPERS_PATH', ABSPATH. 'App/helpers/');
...

所以,既然你已经全部定义了,如果你需要移动一个文件,让我们说一个文件夹转发示例:

root / App / Plugins / Utils

只是inlucde require_once '../../../app-config.php';

显然我认为你不是每次都改变路径=)无论如何你需要这样做总是更容易改变一个文件包含而不是数百个。

希望这对你有意义=)

答案 1 :(得分:2)

  

我在一些项目中看到人们使用dirname(FILE)。有什么意义,我的意思是,为什么不简单地把它留下来,因为dirname无论如何都是相对的(取决于文件所在的位置)?

无论如何,这都与包含路径有关。 dirname( __FILE__ )(或只是PHP中的__DIR__&gt; = 5.3)就在那里,您可以从每个位置运行该文件。如果您使用相对路径,则值为“。”。可能会改变。参见:

berry @ berry-pc:〜% cat so.php

<?php
var_dump( realpath( '.' ) );
var_dump( realpath( __DIR__ ) );

berry @ berry-pc:〜% php so.php

string(11) "/home/berry"
string(11) "/home/berry"

berry @ berry-pc:〜% cd foo

berry @ berry-pc:〜/ foo% php ../ so.php

string(15) "/home/berry/foo"
string(11) "/home/berry"

因此,它是相对的,但它相对于当前的工作目录,而不是文件所在的目录。这就是为什么你要为此使用__DIR__。顺便说一下;是的,我不会移动文件很多。如果我这样做,我将不得不更新对该文件的每次调用,虽然我不再需要或包含很多,因为我使用的是Autoloader

至于我所指的其他文件(例如模板文件),我手动设置路径,但一次。然后我引用$path . '/filename.php';,以便稍后更改。

答案 2 :(得分:1)

取决于您的用法,定义一个常量来保存应用程序路径是常见的做法之一

不要使用变量,因为它可能会在应用程序的某处覆盖并可能破坏您的应用程序

与符号链接(符号创建分支)结合起来更好

application dirs
===============================
/home/latest         -> symlink
/home/testing        -> symlink
/home/20111202000000 -> latest development version
/home/20111201000000 -> yesterday stable release

所以,你可以用符号链接 / home / testing - &gt; / home / 20111202000000保持稳定版本,
/ home / latest - &gt; /家庭/ 201112.01亿

通过这种方式,您无需冒险在进行某些测试/开发时破坏生产站点,并且可以轻松转移开发目录

答案 3 :(得分:1)

我总是使用绝对路径,但我也会使用引导文件启动任何自定义PHP项目,其中我根据从$_SERVER中提取的值将最常用的路径定义为常量。

这是我定义根路径的方式:

define("LOCAL_PATH_ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("HTTP_PATH_ROOT", isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : '_UNKNOWN_'));

路径LOCAL_PATH_ROOT是文档根目录。当通过HTTP访问相同路径时,路径HTTP_PATH_ROOT是等效的。

此时,可以使用以下代码将任何本地路径转换为HTTP路径:

str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, $my_path)

如果要确保与基于Windows的服务器兼容,则还需要使用URL分隔符替换目录分隔符:

str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, str_replace(DIRECTORY_SEPARATOR, '/', $my_path))

这是我用于PHP PowerTools boilerplate的完整引导代码:

defined('LOCAL_PATH_BOOTSTRAP') || define("LOCAL_PATH_BOOTSTRAP", __DIR__);

// -----------------------------------------------------------------------
// DEFINE SEPERATOR ALIASES
// -----------------------------------------------------------------------
define("URL_SEPARATOR", '/');
define("DS", DIRECTORY_SEPARATOR);
define("PS", PATH_SEPARATOR);
define("US", URL_SEPARATOR);

// -----------------------------------------------------------------------
// DEFINE ROOT PATHS
// -----------------------------------------------------------------------
define("RELATIVE_PATH_ROOT", '');
define("LOCAL_PATH_ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("HTTP_PATH_ROOT",
        isset($_SERVER["HTTP_HOST"]) ?
        $_SERVER["HTTP_HOST"] : (
        isset($_SERVER["SERVER_NAME"]) ?
        $_SERVER["SERVER_NAME"] : '_UNKNOWN_'));

// -----------------------------------------------------------------------
// DEFINE RELATIVE PATHS
// -----------------------------------------------------------------------
define("RELATIVE_PATH_BASE",
        str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, getcwd()));
define("RELATIVE_PATH_APP", dirname(RELATIVE_PATH_BASE));
define("RELATIVE_PATH_LIBRARY", RELATIVE_PATH_APP . DS . 'vendor');
define("RELATIVE_PATH_HELPERS", RELATIVE_PATH_BASE);
define("RELATIVE_PATH_TEMPLATE", RELATIVE_PATH_BASE . DS . 'templates');
define("RELATIVE_PATH_CONFIG", RELATIVE_PATH_BASE . DS . 'config');
define("RELATIVE_PATH_PAGES", RELATIVE_PATH_BASE . DS . 'pages');
define("RELATIVE_PATH_ASSET", RELATIVE_PATH_BASE . DS . 'assets');
define("RELATIVE_PATH_ASSET_IMG", RELATIVE_PATH_ASSET . DS . 'img');
define("RELATIVE_PATH_ASSET_CSS", RELATIVE_PATH_ASSET . DS . 'css');
define("RELATIVE_PATH_ASSET_JS", RELATIVE_PATH_ASSET . DS . 'js');

// -----------------------------------------------------------------------
// DEFINE LOCAL PATHS
// -----------------------------------------------------------------------
define("LOCAL_PATH_BASE", LOCAL_PATH_ROOT . RELATIVE_PATH_BASE);
define("LOCAL_PATH_APP", LOCAL_PATH_ROOT . RELATIVE_PATH_APP);
define("LOCAL_PATH_LIBRARY", LOCAL_PATH_ROOT . RELATIVE_PATH_LIBRARY);
define("LOCAL_PATH_HELPERS", LOCAL_PATH_ROOT . RELATIVE_PATH_HELPERS);
define("LOCAL_PATH_TEMPLATE", LOCAL_PATH_ROOT . RELATIVE_PATH_TEMPLATE);
define("LOCAL_PATH_CONFIG", LOCAL_PATH_ROOT . RELATIVE_PATH_CONFIG);
define("LOCAL_PATH_PAGES", LOCAL_PATH_ROOT . RELATIVE_PATH_PAGES);
define("LOCAL_PATH_ASSET", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET);
define("LOCAL_PATH_ASSET_IMG", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_IMG);
define("LOCAL_PATH_ASSET_CSS", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_CSS);
define("LOCAL_PATH_ASSET_JS", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_JS);

// -----------------------------------------------------------------------
// DEFINE URL PATHS
// -----------------------------------------------------------------------
if (US === DS) { // needed for compatibility with windows
    define("HTTP_PATH_BASE", HTTP_PATH_ROOT . RELATIVE_PATH_BASE);
    define("HTTP_PATH_APP", HTTP_PATH_ROOT . RELATIVE_PATH_APP);
    define("HTTP_PATH_LIBRARY", false);
    define("HTTP_PATH_HELPERS", false);
    define("HTTP_PATH_TEMPLATE", false);
    define("HTTP_PATH_CONFIG", false);
    define("HTTP_PATH_PAGES", false);
    define("HTTP_PATH_ASSET", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET);
    define("HTTP_PATH_ASSET_IMG", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_IMG);
    define("HTTP_PATH_ASSET_CSS", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_CSS);
    define("HTTP_PATH_ASSET_JS", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_JS);
} else {
    define("HTTP_PATH_BASE", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_BASE));
    define("HTTP_PATH_APP", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_APP));
    define("HTTP_PATH_LIBRARY", false);
    define("HTTP_PATH_HELPERS", false);
    define("HTTP_PATH_TEMPLATE", false);
    define("HTTP_PATH_CONFIG", false);
    define("HTTP_PATH_PAGES", false);
    define("HTTP_PATH_ASSET", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_ASSET));
    define("HTTP_PATH_ASSET_IMG", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_ASSET_IMG));
    define("HTTP_PATH_ASSET_CSS", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_ASSET_CSS));
    define("HTTP_PATH_ASSET_JS", HTTP_PATH_ROOT .
            str_replace(DS, US, RELATIVE_PATH_ASSET_JS));
}

// -----------------------------------------------------------------------
// DEFINE REQUEST PARAMETERS
// -----------------------------------------------------------------------
define("REQUEST_QUERY",
        isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] != '' ?
        $_SERVER["QUERY_STRING"] : false);
define("REQUEST_METHOD",
        isset($_SERVER["REQUEST_METHOD"]) ?
        strtoupper($_SERVER["REQUEST_METHOD"]) : false);
define("REQUEST_STATUS",
        isset($_SERVER["REDIRECT_STATUS"]) ?
        $_SERVER["REDIRECT_STATUS"] : false);
define("REQUEST_PROTOCOL",
        isset($_SERVER["HTTP_ORIGIN"]) ?
        substr($_SERVER["HTTP_ORIGIN"], 0,
        strpos($_SERVER["HTTP_ORIGIN"], '://') + 3) : 'http://');
define("REQUEST_PATH",
        isset($_SERVER["REQUEST_URI"]) ?
        str_replace(RELATIVE_PATH_BASE, '',
        $_SERVER["REQUEST_URI"]) : '_UNKNOWN_');
define("REQUEST_PATH_STRIP_QUERY",
        REQUEST_QUERY ?
        str_replace('?' . REQUEST_QUERY, '', REQUEST_PATH) : REQUEST_PATH);

// -----------------------------------------------------------------------
// DEFINE SITE PARAMETERS
// -----------------------------------------------------------------------
define("PRODUCTION", false);
define("PAGE_PATH_DEFAULT", US . 'index');
define("PAGE_PATH",
        (REQUEST_PATH_STRIP_QUERY === US) ?
        PAGE_PATH_DEFAULT : REQUEST_PATH_STRIP_QUERY);

如果将上述代码添加到您自己的项目中,此时输出所有用户常量(可以使用get_defined_constants(true)输出的结果应该看起来像这样:

array (
  'LOCAL_PATH_BOOTSTRAP' => '/var/www/libraries/backend/Data/examples',
  'URL_SEPARATOR' => '/',
  'DS' => '/',
  'PS' => ':',
  'US' => '/',
  'RELATIVE_PATH_ROOT' => '',
  'LOCAL_PATH_ROOT' => '/var/www',
  'HTTP_PATH_ROOT' => 'localhost:8888',
  'RELATIVE_PATH_BASE' => '/libraries/backend/Data/examples',
  'RELATIVE_PATH_APP' => '/libraries/backend/Data',
  'RELATIVE_PATH_LIBRARY' => '/libraries/backend/Data/vendor',
  'RELATIVE_PATH_HELPERS' => '/libraries/backend/Data/examples',
  'RELATIVE_PATH_TEMPLATE' => '/libraries/backend/Data/examples/templates',
  'RELATIVE_PATH_CONFIG' => '/libraries/backend/Data/examples/config',
  'RELATIVE_PATH_PAGES' => '/libraries/backend/Data/examples/pages',
  'RELATIVE_PATH_ASSET' => '/libraries/backend/Data/examples/assets',
  'RELATIVE_PATH_ASSET_IMG' => '/libraries/backend/Data/examples/assets/img',
  'RELATIVE_PATH_ASSET_CSS' => '/libraries/backend/Data/examples/assets/css',
  'RELATIVE_PATH_ASSET_JS' => '/libraries/backend/Data/examples/assets/js',
  'LOCAL_PATH_BASE' => '/var/www/libraries/backend/Data/examples',
  'LOCAL_PATH_APP' => '/var/www/libraries/backend/Data',
  'LOCAL_PATH_LIBRARY' => '/var/www/libraries/backend/Data/vendor',
  'LOCAL_PATH_HELPERS' => '/var/www/libraries/backend/Data/examples',
  'LOCAL_PATH_TEMPLATE' => '/var/www/libraries/backend/Data/examples/templates',
  'LOCAL_PATH_CONFIG' => '/var/www/libraries/backend/Data/examples/config',
  'LOCAL_PATH_PAGES' => '/var/www/libraries/backend/Data/examples/pages',
  'LOCAL_PATH_ASSET' => '/var/www/libraries/backend/Data/examples/assets',
  'LOCAL_PATH_ASSET_IMG' => '/var/www/libraries/backend/Data/examples/assets/img',
  'LOCAL_PATH_ASSET_CSS' => '/var/www/libraries/backend/Data/examples/assets/css',
  'LOCAL_PATH_ASSET_JS' => '/var/www/libraries/backend/Data/examples/assets/js',
  'HTTP_PATH_BASE' => 'localhost:8888/libraries/backend/Data/examples',
  'HTTP_PATH_APP' => 'localhost:8888/libraries/backend/Data',
  'HTTP_PATH_LIBRARY' => false,
  'HTTP_PATH_HELPERS' => false,
  'HTTP_PATH_TEMPLATE' => false,
  'HTTP_PATH_CONFIG' => false,
  'HTTP_PATH_PAGES' => false,
  'HTTP_PATH_ASSET' => 'localhost:8888/libraries/backend/Data/examples/assets',
  'HTTP_PATH_ASSET_IMG' => 'localhost:8888/libraries/backend/Data/examples/assets/img',
  'HTTP_PATH_ASSET_CSS' => 'localhost:8888/libraries/backend/Data/examples/assets/css',
  'HTTP_PATH_ASSET_JS' => 'localhost:8888/libraries/backend/Data/examples/assets/js',
  'REQUEST_QUERY' => false,
  'REQUEST_METHOD' => 'GET',
  'REQUEST_STATUS' => false,
  'REQUEST_PROTOCOL' => 'http://',
  'REQUEST_PATH' => '/',
  'REQUEST_PATH_STRIP_QUERY' => '/',
  'PRODUCTION' => false,
  'PAGE_PATH_DEFAULT' => '/index',
  'PAGE_PATH' => '/index',
)

答案 4 :(得分:0)

使用操作码缓存或许多require / include语句时,从性能的角度来看,绝对路径更好(尽管当你开始包含数百个文件时它们才会引人注意,就像使用Zend / Symfony这样的框架时可能会发生的那样/等)。

使用相对路径,操作码缓存和php必须在每次运行之前计算出文件realpath,如果它已经知道该文件并且是否需要再次加载它。 PHP内部维护文件的散列映射到文件位置,只要不必每次都执行上述计算,它就非常快。