Абсолютные и относительные пути - PullRequest
13 голосов
/ 02 декабря 2011

Если я использую абсолютные пути, я не могу переместить весь каталог в новое место. Если я использую относительные пути, я не могу переместить отдельные файлы в новые места.

Какое решение здесь? Вы настраиваете файл конфигурации, который содержит корневой путь и идет оттуда? Или у вас есть такое правило: никогда не перемещать файлы?

Я видел в некоторых проектах, что люди используют dirname ( FILE ). Какой смысл в этом, я имею в виду, почему бы просто не пропустить его, так как dirname в любом случае является относительным (в зависимости от того, где находится файл)?

Ответы [ 5 ]

15 голосов
/ 02 декабря 2011

Вы должны использовать файл конфигурации, который будет включен в первую строку каждого файла, например, ваше приложение выглядит так

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 / Плагины / Утилиты

просто включено require_once '../../../app-config.php';

очевидноЯ полагаю, что вы не меняете пути каждый раз =) в любом случае, если вам нужно сделать это, всегда проще изменить одно включение файла вместо сотен.

надеюсь, это имеет смысл для вас =)

2 голосов
/ 02 декабря 2011

Я видел в некоторых проектах, что люди используют dirname (FILE).Какой смысл в этом, я имею в виду, почему бы просто не опустить его, так как имя каталога в любом случае относительно (в зависимости от того, где находится файл)?

В любом случае, это относительно пути включения.dirname( __FILE__ ) (или просто __DIR__ в PHP> = 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__ за это.И кстати;да, я не очень много перемещаю файлы.Однако, если я сделаю это, мне придется обновлять каждый вызов этого файла, хотя я больше не требую и не включаю очень много, поскольку я использую Автозагрузчик .

Что касается других файлов, на которые я ссылаюсь (например, файлов шаблонов), я установил путь вручную, но один раз .Затем я обращаюсь к $path . '/filename.php';, так что потом легче изменить.

1 голос
/ 08 ноября 2014

Я всегда использую абсолютные пути, но я также запускаю любой пользовательский проект 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_PATH_ROOT является эквивалентным при доступе к тому же пути через HTTP.

На этом этапе преобразование любого локального пути в путь 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 :

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',
)
1 голос
/ 02 декабря 2011

Зависит от вашего использования, определение константы для хранения пути приложения является одной из распространенных практик

Не используйте переменную, так как она может переопределить где-то в вашем приложении и может сломать ваше приложение

Еще лучше объединить с символической ссылкой (символической для создания веток)

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

При этом вам не нужно рисковать, чтобы сломать производственный сайт во время некоторого тестирования / разработки, и вы можете легко перенести каталог разработки

0 голосов
/ 02 декабря 2011

Абсолютные пути лучше с точки зрения производительности при использовании кэша кода операции или большого количества операторов require / include (хотя это заметно только при начале включения сотен файлов, что может случиться при использовании инфраструктуры, такой как Zend / Symfony /etc).

При относительном пути кэш кода операции и php должны каждый раз обрабатывать realpath файлов, прежде чем он сможет работать, если он уже знает о файле и должен ли он загрузить его снова. PHP внутренне поддерживает хэш-карту файлов в расположениях файлов, что очень быстро, если не требуется каждый раз выполнять вышеуказанные вычисления.

...