Relative and absolute paths php

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 ;

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 ;

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 );
>
?>

Читайте также:  Tailwind css text color

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 );
>
?>

Читайте также:  Yandex ru support passport troubleshooting hacked html

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).

Источник

Absolute VS Relative Paths
(and the Document Root)

An is a path from the system root (the topmost folder of an operating system) to another file or directory (folder). The system root is indicated on:

  • Mac/Unix by a forward slash /
  • Windows by a drive letter, colon and backslash, this is usually C:\

A points to the location of a file relative to the ( cwd ). When writing PHP, the current working directory is the folder containing the script that is currently being processed.

If pages use an include in a different folder, when the include is running, the cwd is the folder that holds the include.

This screenshot shows the location of files running on MAMP on a Mac.

Below, you can see some examples of absolute paths that relate to the folders shown in this screenshot.

A file explorer. Inside the htdocs folder there are 3 PHP files (about.php, contact.php and index.php) plus two folders (img and includes). In the includes folder there is a header.php file

The absolute path to index.php is:
/Applications/MAMP/htdocs/index.php

Читайте также:  Битрикс modules main include php

When code in the index.php file is running, the cwd is:
/Applications/MAMP/htdocs/

The absolute path to header.php is:
/Applications/MAMP/htdocs/includes/header.php

When code in the header.php file is running, the cwd is:
/Applications/MAMP/htdocs/includes/

The index.php file can include header.php using the relative path: includes/header.php

In index.php , the relative path img/logo.png would point to the logo.png file in the img folder.

If a path starts with ../ it indicates that the file is up a directory from the current working directory.

In header.php , the relative path ../img/logo.png would point to the logo.png file in the img folder.

Document Root Folder

Websites have another type of root folder called the . This is a folder on the web server that maps to the domain name/hostname.

For example, when a web server hosts the domain name:
http://example.com

It could map to the following folder on the server:
/var/www/examplecom/

Every file that a browser can request must be inside the document root folder, including PHP pages, images, CSS and JavaScript files.

If you requested the URL:
http://example.com/index.php
the web server would run the file:
/var/www/examplecom/index.php .

If you requested the URL:
http://example.com/about.php ,
the web server would run the file:
/var/www/examplecom/about.php .

The default document root folder for:
MAMP on Mac is /Applications/MAMP/htdocs/
XAMPP on PC is C:\XAMPP\htdocs\

Root Relative URLs

When a path that is used in a web page starts with a forward slash, the forward slash indicates the document root folder.

A path will start with a forward slash, and is followed by the path after that is relative from the document root folder.

In the folder structure shown in the screenshot above, any page could use the path /img/logo.png to refer to the logo.png file in the img folder.

You should only use root relative paths in URLs for files that the browser might request. As far as the PHP interpreter is concerned, the forward slash would refer to a different folder.

When your PHP code tries to refer to another file, you should use absolute paths.

Sites often store the path to the document root folder in a constant, then use this at the start of any paths to other files. This has two advantages:

  • It saves typing the path to the document root
  • If the path to the document root folder changes (perhaps because the site moves to another server), the path only needs updating in one place

Источник

Оцените статью