2010-05-02 1 views
2

Мне нужен быстрый и надежный способ сопоставления абсолютного или относительного местного пути (скажем ./images/Mafalda.jpg) до соответствующего абсолютного URL-адреса, до сих пор мне удалось подойти с этим:Сопоставление абсолютных/относительных (локальных) путей к абсолютным URL-адресам

function Path($path) 
{ 
    if (file_exists($path) === true) 
    { 
     return rtrim(str_replace('\\', '/', realpath($path)), '/') . (is_dir($path) ? '/' : ''); 
    } 

    return false; 
} 

function URL($path) 
{ 
    $path = Path($path); 

    if ($path !== false) 
    { 
     return str_replace($_SERVER['DOCUMENT_ROOT'], getservbyport($_SERVER['SERVER_PORT'], 'tcp') . '://' . $_SERVER['HTTP_HOST'], $path); 
    } 

    return false; 
} 

URL('./images/Mafalda.jpg'); // http://domain.com/images/Mafalda.jpg 

Кажется, что работает, как ожидалось, но так как это очень важная особенность для моего приложения я хочу спросить, если кто-нибудь может обнаружить любую проблему, что я, возможно, пропустили и оптимизации, также приветствуются, так как я m будет использовать эту функцию несколько раз за каждый запрос. Кто угодно?

+5

Почему downvotes? – egrunin

+1

Возможно, потому что они думают, что это должна быть wiki? (Я не уверен, сам) –

ответ

1

Одной из потенциальных проблем, на которые следует обратить внимание, являются символические ссылки. Если DOCUMENT_ROOT содержит часть, символическую ссылку, все взорвется (поскольку realpath() расширит эту символическую ссылку).

Конечно, решение может быть таким же простым, как и перенос $ _SERVER ['DOCUMENT_ROOT'] в realpath().

+0

Это было бы проблемой, лучше брось вызов 'is_link()' там, спасибо. Можете ли вы придумать какие-либо оптимизации, чтобы сделать это быстрее? –

+0

Не уверен. Я уверен, что материал, связанный с файловой системой, будет самым медленным. Но вам это нужно. Str_replaces должны быть быстрыми. – timdev

+1

Также: не уверен is_link() - это путь. Вам нужно будет проверить каждую часть пути. Возможно, более разумно просто позволить realpath() сделать это. Пока вы всегда имеете дело с реальными путями, вы знаете, что символические ссылки не будут проблемой. – timdev

0

Я всегда абсолютный путь, но я также запускаю любой пользовательский 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, вы должны заменить каталог Seperator с 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', 
)