realpath
realpath() expands all symbolic links and resolves references to /./ , /../ and extra / characters in the input path and returns the canonicalized absolute pathname.
Parameters
Note:
Whilst a path must be supplied, the value can be an empty string. In this case, the value is interpreted as the current directory.
Return Values
Returns the canonicalized absolute pathname on success. The resulting path will have no symbolic link, /./ or /../ components. Trailing delimiters, such as \ and / , are also removed.
realpath() returns false on failure, e.g. if the file does not exist.
Note:
The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return false .
Note:
For case-insensitive filesystems realpath() may or may not normalize the character case.
Note:
The function realpath() will not work for a file which is inside a Phar as such path would be a virtual path, not a real one.
Note:
On Windows, junctions and symbolic links to directories are only expanded by one level.
Note: Because PHP’s integer type is signed and many platforms use 32bit integers, some filesystem functions may return unexpected results for files which are larger than 2GB.
Examples
Example #1 realpath() example
chdir ( ‘/var/www/’ );
echo realpath ( ‘./../../etc/passwd’ ) . PHP_EOL ;
?php
echo realpath ( ‘/tmp/’ ) . PHP_EOL ;
?>
The above example will output:
Example #2 realpath() on Windows
On windows realpath() will change unix style paths to windows style.
echo realpath ( ‘/windows/system32’ ), PHP_EOL ;
?php
echo realpath ( ‘C:\Program Files\\’ ), PHP_EOL ;
?>
The above example will output:
C:\WINDOWS\System32 C:\Program Files
See Also
- basename() — Returns trailing name component of path
- dirname() — Returns a parent directory’s path
- pathinfo() — Returns information about a file path
User Contributed Notes 17 notes
Because realpath() does not work on files that do not
exist, I wrote a function that does.
It replaces (consecutive) occurences of / and \\ with
whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine.
Paths returned by get_absolute_path() contain no
(back)slash at position 0 (beginning of the string) or
position -1 (ending)
function get_absolute_path ( $path ) $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 ;
>
>
return implode ( DIRECTORY_SEPARATOR , $absolutes );
>
?>
A test:
var_dump ( get_absolute_path ( ‘this/is/../a/./test/.///is’ ));
?>
Returns: string(14) «this/a/test/is»
As you can so, it also produces Yoda-speak. 🙂
namespace MockingMagician \ Organic \ Helper ;
class Path
/**
* There is a method that deal with Sven Arduwie proposal https://www.php.net/manual/en/function.realpath.php#84012
* And runeimp at gmail dot com proposal https://www.php.net/manual/en/function.realpath.php#112367
* @param string $path
* @return string
*/
public static function getAbsolute ( string $path ): string
// Cleaning path regarding OS
$path = mb_ereg_replace ( ‘\\\\|/’ , DIRECTORY_SEPARATOR , $path , ‘msr’ );
// Check if path start with a separator (UNIX)
$startWithSeparator = $path [ 0 ] === DIRECTORY_SEPARATOR ;
// Check if start with drive letter
preg_match ( ‘/^[a-z]:/’ , $path , $matches );
$startWithLetterDir = isset( $matches [ 0 ]) ? $matches [ 0 ] : false ;
// Get and filter empty sub paths
$subPaths = array_filter ( explode ( DIRECTORY_SEPARATOR , $path ), ‘mb_strlen’ );
$absolutes = [];
foreach ( $subPaths as $subPath ) if ( ‘.’ === $subPath ) continue;
>
// if $startWithSeparator is false
// and $startWithLetterDir
// and (absolutes is empty or all previous values are ..)
// save absolute cause that’s a relative and we can’t deal with that and just forget that we want go up
if ( ‘..’ === $subPath
&& ! $startWithSeparator
&& ! $startWithLetterDir
&& empty( array_filter ( $absolutes , function ( $value ) < return !( '..' === $value ); >))
) $absolutes [] = $subPath ;
continue;
>
if ( ‘..’ === $subPath ) array_pop ( $absolutes );
continue;
>
$absolutes [] = $subPath ;
>
return
(( $startWithSeparator ? DIRECTORY_SEPARATOR : $startWithLetterDir ) ?
$startWithLetterDir . DIRECTORY_SEPARATOR : »
). implode ( DIRECTORY_SEPARATOR , $absolutes );
>
/**
* Examples
*
* echo Path::getAbsolute(‘/one/two/../two/./three/../../two’); => /one/two
* echo Path::getAbsolute(‘../one/two/../two/./three/../../two’); => ../one/two
* echo Path::getAbsolute(‘../.././../one/two/../two/./three/../../two’); => ../../../one/two
* echo Path::getAbsolute(‘../././../one/two/../two/./three/../../two’); => ../../one/two
* echo Path::getAbsolute(‘/../one/two/../two/./three/../../two’); => /one/two
* echo Path::getAbsolute(‘/../../one/two/../two/./three/../../two’); => /one/two
* echo Path::getAbsolute(‘c:\.\..\one\two\..\two\.\three\..\..\two’); => c:/one/two
*
*/
>
Needed a method to normalize a virtual path that could handle .. references that go beyond the initial folder reference. So I created the following.
function normalizePath ( $path )
$parts = array(); // Array to build a new path from the good parts
$path = str_replace ( ‘\\’ , ‘/’ , $path ); // Replace backslashes with forwardslashes
$path = preg_replace ( ‘/\/+/’ , ‘/’ , $path ); // Combine multiple slashes into a single slash
$segments = explode ( ‘/’ , $path ); // Collect path segments
$test = » ; // Initialize testing variable
foreach( $segments as $segment )
if( $segment != ‘.’ )
$test = array_pop ( $parts );
if( is_null ( $test ))
$parts [] = $segment ;
else if( $segment == ‘..’ )
if( $test == ‘..’ )
$parts [] = $test ;
if( $test == ‘..’ || $test == » )
$parts [] = $segment ;
>
else
$parts [] = $test ;
$parts [] = $segment ;
>
>
>
return implode ( ‘/’ , $parts );
>
?>
Will convert /path/to/test/.././..//..///..///../one/two/../three/filename
to ../../one/three/filename
realpath() is just a system/library call to actual realpath() function supported by OS. It does not work on a path as a string, but also resolves symlinks. The resulting path might significantly differs from the input even when absolute path is given. No function in this notes resolves that.
The suggestion on the realpath man page is to look for an existing parent directory. Here is an example:
function resolvePath ( $path ) if( DIRECTORY_SEPARATOR !== ‘/’ ) $path = str_replace ( DIRECTORY_SEPARATOR , ‘/’ , $path );
>
$search = explode ( ‘/’ , $path );
$search = array_filter ( $search , function( $part ) return $part !== ‘.’ ;
>);
$append = array();
$match = false ;
while( count ( $search ) > 0 ) $match = realpath ( implode ( ‘/’ , $search ));
if( $match !== false ) break;
>
array_unshift ( $append , array_pop ( $search ));
>;
if( $match === false ) $match = getcwd ();
>
if( count ( $append ) > 0 ) $match .= DIRECTORY_SEPARATOR . implode ( DIRECTORY_SEPARATOR , $append );
>
return $match ;
>
?>
The result will retrieve absolute path for non-existing relative path. Even if a path does not exists, there should be existing directory somewhere, for which the realpath could be obtained. If this is not within the relative path (i.e. even current working directory does not exists), getcwd() will retrieve absolute path, so some absolute path is returned (although in that case the PHP process could have huge problems).
Note: If you use this to check if a file exists, it’s path will be cached, and returns true even if the file is removed (use file_exists instead).
Make a path work both on linux and Windows
In Linux, the path separator is / . In Windows, it is either \ or / . So just use forward slashes and you will be fine.
APPLICATION_PATH . '/logs/app.log'
@sanders, That’s not a problem. Windows understands that path. In Windows you can mix forward and backward slashes in a single path.
I’ve seen this being said before but it seems to conflict with the information here: stackoverflow.com/questions/2410354/…
@Matt, that’s a different issue. In that question someone was not escaping backslashes in their string, and \n was being converted to a newline. If you are going to use backslashes, you have to escape them properly. That’s a basic php issue though, so it’s not directly related to this.
Also note that the problem in that question only arose because they were using double-quotes, where \n is interpreted that way. If you use single quotes (the the OP did in the example here) then \n is not interpreted in any special way, and the literal works fine as-is.
You can also use DIRECTORY_SEPARATOR constant instead of \ or / . Usually you’ll want to redefine it to have shorter name, like
define('DS', DIRECTORY_SEPARATOR); $filename = APP . DS . 'logs' . DS . 'file.txt';
if you want to communicate two or more app of your site, this trick will serve you much
$ Document_root = realpath ( \ filter_input ( INPUT_SERVER , ' DOCUMENT_ROOT '));
this is to convert the route you back real path and then just have to navigate between directories with the DIRECTORY_SEPARATOR without worrying about the operating system installed on your machine or web server
pathinfo
pathinfo() возвращает информацию о path в виде ассоциативного массива или строки, в зависимости от flags .
Замечание:
Подробнее о получении информации о текущем пути, можно почитать в разделе Предопределённые зарезервированные переменные.
Замечание:
pathinfo() оперирует входной строкой и не знает фактическую файловую систему или компоненты пути, такие как » .. «.
Замечание:
Только в системах Windows символ \ будет интерпретироваться как разделитель каталогов. В других системах он будет рассматриваться как любой другой символ.
pathinfo() учитывает настройки локали, поэтому для корректной обработки пути с многобайтными символами должна быть установлена соответствующая локаль с помощью функции setlocale() .
Список параметров
Если указан, то задаёт, какой из элементов пути будет возвращён: PATHINFO_DIRNAME , PATHINFO_BASENAME , PATHINFO_EXTENSION и PATHINFO_FILENAME .
Если flags не указан, то возвращаются все доступные элементы.
Возвращаемые значения
Если параметр flags не передан, то возвращаемый ассоциативный массив ( array ) будет содержать следующие элементы: dirname , basename , extension (если есть) и filename .
Замечание:
Если path содержит больше одного расширения, то PATHINFO_EXTENSION возвращает только последний и PATHINFO_FILENAME удаляет только последнее расширение. (смотрите пример ниже).
Замечание:
Если path не содержит расширения, то не будет возвращён элемент extension (смотрите ниже второй пример).
Замечание:
Если basename параметра path начинается с точки, то все последующие символы интерпретируются как расширение файла ( extension ) и имя файла filename будет пустым (смотрите третий пример).
Если указан параметр flags , будет возвращена строка ( string ), содержащая указанный элемент.
Примеры
Пример #1 Пример использования функции pathinfo()
$path_parts = pathinfo ( ‘/www/htdocs/inc/lib.inc.php’ );
?php
echo $path_parts [ ‘dirname’ ], «\n» ;
echo $path_parts [ ‘basename’ ], «\n» ;
echo $path_parts [ ‘extension’ ], «\n» ;
echo $path_parts [ ‘filename’ ], «\n» ;
?>
Результат выполнения данного примера:
/www/htdocs/inc lib.inc.php php lib.inc
Пример #2 Пример с pathinfo() , показывающий разницу между null и отсутствием расширения
$path_parts = pathinfo ( ‘/path/emptyextension.’ );
var_dump ( $path_parts [ ‘extension’ ]);
?php
$path_parts = pathinfo ( ‘/path/noextension’ );
var_dump ( $path_parts [ ‘extension’ ]);
?>
Результатом выполнения данного примера будет что-то подобное:
string(0) "" Notice: Undefined index: extension in test.php on line 6 NULL
Пример #3 Пример pathinfo() для файла, начинающегося с точки
Результатом выполнения данного примера будет что-то подобное:
Array ( [dirname] => /some/path [basename] => .test [extension] => test [filename] => )
Пример #4 Пример использования pathinfo() с разыменованием массива
Параметр flags не является битовой маской. Может быть предоставлено только одно значение. Чтобы выбрать только ограниченный набор разобранных значений, используйте деструктуризацию массива следующим образом:
[ ‘basename’ => $basename , ‘dirname’ => $dirname ] = pathinfo ( ‘/www/htdocs/inc/lib.inc.php’ );
?php
var_dump ( $basename , $dirname );
?>
Результатом выполнения данного примера будет что-то подобное:
string(11) "lib.inc.php" string(15) "/www/htdocs/inc"
Смотрите также
- dirname() — Возвращает имя родительского каталога из указанного пути
- basename() — Возвращает последний компонент имени из указанного пути
- parse_url() — Разбирает URL и возвращает его компоненты
- realpath() — Возвращает канонизированный абсолютный путь к файлу