【问题标题】:Absolute vs. relative paths绝对路径与相对路径
【发布时间】:2012-01-11 11:53:18
【问题描述】:

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

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

我在一些项目中看到人们使用 dirname(FILE)。我的意思是,为什么不简单地将其排除在外,因为目录名是相对的(取决于文件所在的位置)?

【问题讨论】:

  • dirname(__FILE__) 或__DIR__ 的使用是即使包含文件,它仍然会返回当前脚本的目录。如果您有一个包含 dir/script.php 的文件,则 script.php 中的默认包含路径将是根目录,而不是 dir/。
  • @Frank Vilea:您是否设置了一个包含根路径并从那里开始的配置文件? 是
  • 我自己在这方面做得很差,但我想这个想法是将这两者混合起来。 Bu 添加主脚本的绝对路径和脚本中包含和使用的文件的相对路径。当然,如果不更改相对路径声明中的某些内容,您永远不能使用相对路径移动任何文件。
  • 我在这里是@aSeptik,在你的配置文件中设置一个保存根路径的设置通常是最好的解决方案。

标签: php relative-path absolute-path


【解决方案1】:

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

根/应用程序/插件

在您的根目录中: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/');
...

所以,既然你已经全部定义好了,如果你需要移动一个文件,比如说一个文件夹向前的例子:

根/应用程序/插件/实用程序

只需要require_once '../../../app-config.php';

显然,我认为您不会每次都更改路径 =) 无论如何,如果您需要这样做,更改一个文件包含而不是数百个文件总是更简单。

希望这对你有意义 =)

【讨论】:

    【解决方案2】:

    我在一些项目中看到人们使用 dirname(FILE)。我的意思是,为什么不简单地将其排除在外,因为目录名是相对的(取决于文件所在的位置)?

    无论如何,它是相对于包含路径的。 dirname( __FILE__ )(或在 PHP >= 5.3 中只是 __DIR__)在那里,因此您可以从每个位置运行文件。如果您使用相对路径,则值“。”可能会改变。见:

    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';,这样以后更容易改。

    【讨论】:

    • 感谢这篇非常详细的帖子。现在它是有道理的。自动加载功能看起来也很整洁。
    【解决方案3】:

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

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

    与symlink结合更好(符号创建分支)

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

    所以,你可以使用符号链接
    /home/testing -> /home/20111202000000 同时保持稳定版本,
    /home/latest -> /home/20111201000000

    有了这个,您不必冒险在进行一些测试/开发时破坏您的生产站点,并且您可以轻松地转移您的开发目录

    【讨论】:

      【解决方案4】:

      我总是使用绝对路径,但我也会使用引导文件启动任何自定义 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',
      )
      

      【讨论】:

      • 这真是令人惊叹的优雅。
      【解决方案5】:

      从性能的角度来看,绝对路径在使用操作码缓存或大量 require/include 语句时会更好(尽管它仅在您开始包含数百个文件时才明显,这可能在使用 Zend/Symfony 之类的框架时发生/等)。

      使用相对路径,操作码缓存和 php 必须每次都计算出文件的实际路径,然后才能确定它是否已经知道该文件以及是否需要再次加载它。 PHP 在内部维护了一个文件到文件位置的哈希映射,只要不必每次都进行上述计算,这非常快。

      【讨论】:

        猜你喜欢
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2010-09-15
        • 2013-04-17
        相关资源
        最近更新 更多