Absolute vs. relative paths

后端 未结 5 825
温柔的废话
温柔的废话 2020-11-30 03:02

If I use absolute paths, I can\'t move the whole directory to a new location. If I use relative paths, I can\'t move individual files to new locations.

What\'s the s

相关标签:
5条回答
  • 2020-11-30 03:05

    you should use a config file that will be included in each file first line, for example your app look like this

    root / App / Plugins

    inside your root dir : app-config.php

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

    now, suppose you have to include a plugin file, so

    inside your Plugin dir : my-plugin.php

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

    now everything below this line can use ABSPATH

    example do you want to load an image

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

    now, the thing is more simple if your app is designed to automatically load some files like

    plugin-widget-1.php
    

    so that everything inside this file or any other file loaded by the my-plugin.php file can use the ABSPATH without include each time the app-config.php file.

    with this in mind you can have all the short-hand you want into the app-config.php example

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

    so, now that you have all defined, if you need to move a file, let's say one folder forward example:

    root / App / Plugins / Utils

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

    obviously i suppose that you are not changing paths each time =) anyway if you need to do so is always more simple to change one file inclusion instead of hundreds.

    hope this make sense to you =)

    0 讨论(0)
  • 2020-11-30 03:05

    I've seen in some projects that people use dirname(FILE). What is the point of that, I mean, why not simply leave it out since the dirname is relative anyway (depending on where the file sits)?

    It's relative to the include path, anyway. The dirname( __FILE__ ) (or just __DIR__ in PHP >= 5.3) is there so you can run the file from every location. In case you're using relative paths, the value "." may change. See:

    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"
    

    So, it is relative, but it's relative to the current working directory, not to the directory the file is located in. That's why you'll want to use __DIR__ for this. And by the way; yes, I don't move files around an awful lot. If I do though, I'll have to update every call to that file, although I don't require or include an awful lot anymore, since I'm using an Autoloader.

    As for the other files I'm referring to (such as template files), I set the path manually, but once. I then refer to $path . '/filename.php';, so it's easier to change later.

    0 讨论(0)
  • 2020-11-30 03:06

    I always use absolute paths, but I also start any custom PHP project with a bootstrap file where I define the most commonly used paths as constants, based on values extracted from $_SERVER.

    This is how I define my root paths :

    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_'));
    

    The path LOCAL_PATH_ROOT is the document root. The path HTTP_PATH_ROOT is the equivalent when accessing the same path via HTTP.

    At that point, converting any local path to an HTTP path can be done with the following code :

    str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, $my_path)
    

    If you want to ensure compatibility with Windows based servers, you'll need to replace the directory seperator with a URL seperator as well :

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

    Here's the full bootstrap code that I'm using for the 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);
    

    If you add the above code to your own project, outputting all user constants at this point (which can do with get_defined_constants(true) should give a result that looks somewhat like this :

    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',
    )
    
    0 讨论(0)
  • 2020-11-30 03:23

    Absolute paths are better from a performance point of view when using an opcode cache or lots of require/include statement (although its only noticeable when you start to include hundreds of files, as might happen when using a framework like Zend/Symfony/etc).

    With a relative path the opcode cache and php must work out the files realpath each time before it can work out if it already knows about the file and if it needs to load it again. PHP internally maintains a hashmap of files to file locations which is very quick as long it doesn't have to do the above calculation each time.

    0 讨论(0)
  • 2020-11-30 03:31

    Depends on your usage, define a constant to hold application path is one of the common practice

    Don't use variable as it might get override somewhere in your application and can break your application

    Is even better to combine with symlink (symbolic to create branches)

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

    So, you can symbolic link
    /home/testing -> /home/20111202000000 while keeping the stable version,
    /home/latest -> /home/20111201000000

    With this, you don't have to risk to break your production site while doing some testing/development, and, you can easily shift your development directory

    0 讨论(0)
提交回复
热议问题