Intereting Posts
Создание случайного шестнадцатеричного цветового кода с помощью PHP Проверка триггера Yii на другом поле php singleton database connection, является ли этот код плохой практикой? Как долго длится моя сессия? Преобразование SVG в PNG / JPEG / BMP и наоборот? Как добавить массив со значениями в конфигурации Symfony2? У меня есть png, закодированный base64, как написать образ в файл на PHP? Добавление событий в календарь Outlook с помощью php-скрипта Константы класса PHP – общедоступные, частные или защищенные? Как я могу выбрать и загрузить несколько файлов с помощью HTML и PHP, используя HTTP POST? Как работает сессия? Правила проверки формы для regex_match PHP пытается войти в MSSQL (проверка подлинности Windows) с именем компьютера вместо имени входа возможно ли установить неограниченное время для файла cookie для переменной сеанса? Ошибка DOM – идентификатор «someAnchor», уже определенный в Entity, строка X

Замените realpath PHP ()

По-видимому, realpath очень realpath . В PHP 5.3.1 он вызывает случайные сбои. В 5.3.0 и менее realpath случайным образом терпит неудачу и возвращает false (для той же строки, конечно), плюс он всегда терпит неудачу на realpath – одну и ту же строку дважды и более (и, конечно же, она работает в первый раз).

Кроме того, он настолько ошибочен в более ранних версиях PHP, что он полностью непригоден. Ну … это уже так, так как это непротиворечиво.

Во всяком случае, какие у меня варианты? Может быть, переписать его сам? Это целесообразно?

Solutions Collecting From Web of "Замените realpath PHP ()"

Благодаря коду Свена Ардуви (отмеченному Пеккой ) и некоторой модификации, я построил (надеюсь) лучшую реализацию:

 /** * This function is to replace PHP's extremely buggy realpath(). * @param string The original path, can be relative etc. * @return string The resolved path, it might not exist. */ function truepath($path){ // whether $path is unix or not $unipath=strlen($path)==0 || $path{0}!='/'; // attempts to detect if path is relative in which case, add cwd if(strpos($path,':')===false && $unipath) $path=getcwd().DIRECTORY_SEPARATOR.$path; // resolve path parts (single dot, double dot and double delimiters) $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part) continue; if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } $path=implode(DIRECTORY_SEPARATOR, $absolutes); // resolve any symlinks if(file_exists($path) && linkinfo($path)>0)$path=readlink($path); // put initial separator that could have been lost $path=!$unipath ? '/'.$path : $path; return $path; } 

NB: В отличие от realpath PHP эта функция не возвращает false при ошибке; он возвращает путь, который, насколько это возможно, разрешает эти причуды.

Примечание 2: По-видимому, некоторые люди не могут читать правильно. Truepath () не работает на сетевых ресурсах, включая UNC и URL. Он работает только для локальной файловой системы.

здесь приведен модифицированный код, который также поддерживает пути UNC

 static public function truepath($path) { // whether $path is unix or not $unipath = strlen($path)==0 || $path{0}!='/'; $unc = substr($path,0,2)=='\\\\'?true:false; // attempts to detect if path is relative in which case, add cwd if(strpos($path,':') === false && $unipath && !$unc){ $path=getcwd().DIRECTORY_SEPARATOR.$path; if($path{0}=='/'){ $unipath = false; } } // resolve path parts (single dot, double dot and double delimiters) $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part){ continue; } if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } $path = implode(DIRECTORY_SEPARATOR, $absolutes); // resolve any symlinks if( function_exists('readlink') && file_exists($path) && linkinfo($path)>0 ){ $path = readlink($path); } // put initial separator that could have been lost $path = !$unipath ? '/'.$path : $path; $path = $unc ? '\\\\'.$path : $path; return $path; } 

Я никогда не слышал о таких огромных проблемах с realpath() (я всегда думал, что он просто взаимодействует с некоторыми базовыми функциональными возможностями ОС – будет интересоваться некоторыми ссылками), но пользовательские примечания к странице руководства имеют ряд альтернативных реализаций. Вот один, который выглядит хорошо.

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

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

Я знаю, что это старый поток, но это действительно полезно.

Я встречаю странную проблему Phar :: interceptFileFuncs, когда я реализовал относительный путь в phpctags , realpath() действительно действительно глючит внутри phar.

Благодаря этой теме дайте мне немного света, здесь идет моя реализация, основанная на реализации христианами этой темы и этих комментариев .

Надеюсь, это сработает для вас.

 function relativePath($from, $to) { $fromPath = absolutePath($from); $toPath = absolutePath($to); $fromPathParts = explode(DIRECTORY_SEPARATOR, rtrim($fromPath, DIRECTORY_SEPARATOR)); $toPathParts = explode(DIRECTORY_SEPARATOR, rtrim($toPath, DIRECTORY_SEPARATOR)); while(count($fromPathParts) && count($toPathParts) && ($fromPathParts[0] == $toPathParts[0])) { array_shift($fromPathParts); array_shift($toPathParts); } return str_pad("", count($fromPathParts)*3, '..'.DIRECTORY_SEPARATOR).implode(DIRECTORY_SEPARATOR, $toPathParts); } function absolutePath($path) { $isEmptyPath = (strlen($path) == 0); $isRelativePath = ($path{0} != '/'); $isWindowsPath = !(strpos($path, ':') === false); if (($isEmptyPath || $isRelativePath) && !$isWindowsPath) $path= getcwd().DIRECTORY_SEPARATOR.$path; // resolve path parts (single dot, double dot and double delimiters) $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $pathParts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutePathParts = array(); foreach ($pathParts as $part) { if ($part == '.') continue; if ($part == '..') { array_pop($absolutePathParts); } else { $absolutePathParts[] = $part; } } $path = implode(DIRECTORY_SEPARATOR, $absolutePathParts); // resolve any symlinks if (file_exists($path) && linkinfo($path)>0) $path = readlink($path); // put initial separator that could have been lost $path= (!$isWindowsPath ? '/'.$path : $path); return $path; } 

Для тех пользователей Zend, этот ответ может помочь вам, так как он сделал меня:

 $path = APPLICATION_PATH . "/../directory"; $realpath = new Zend_Filter_RealPath(new Zend_Config(array('exists' => false))); $realpath = $realpath->filter($path); 

В Windows 7 код работает нормально. В Linux существует проблема в том, что созданный путь начинается с (в моем случае) home / xxx, когда он должен начинаться с / home / xxx … т.е. отсутствует начальная /, указывающая корневую папку. Проблема заключается не столько в этой функции, сколько в том, что getcwd возвращает в Linux.