PHP's realpath() function is used to return the absolute path of the specified path and parse the symbolic links, relative paths (such as . and .. ) and so on:
$realPath = realpath('/var/www/html/../index.php');
echo $realPath;
This code will output the absolute path of /var/www/index.php .
A soft link is a reference to another file or directory. It is very common in Linux systems, especially in deployment environments (such as using Nginx root to point to a soft link directory). The problem is:
realpath() will parse and return the real path pointed to by the soft link;
If you rely on paths for permission control or path matching, the path returned by realpath() may be inconsistent with your expectations;
In some scenarios (such as whitelist verification), the path after soft link resolution may bypass your limitations.
Example :
Suppose there is the following file structure:
/data/app/storage/real/
/data/app/storage/link -> /data/app/storage/real/
The code is as follows:
$path = '/data/app/storage/link/file.txt';
echo realpath($path);
The output will be:
/data/app/storage/real/file.txt
At this time, if you expect the return path to contain the word link , the behavior of realpath() does not match your goal.
If you only want to get the absolute path and don't care whether to parse the soft link, you can use the following combination of methods to obtain it:
$absolutePath = rtrim(getcwd(), '/') . '/' . ltrim($relativePath, '/');
This does not resolve the soft link, retaining the original structure of the path you pass in.
You can determine whether the path is a soft link and handle the logic by yourself:
if (is_link($path)) {
$target = readlink($path);
echo "This is a soft link,The goal is:" . $target;
}
You can decide whether to follow the link based on project requirements, or keep the original path.
Here is a path normalization function that does not depend on realpath() :
function normalizePath($path) {
$parts = [];
foreach (explode('/', $path) as $segment) {
if ($segment === '' || $segment === '.') {
continue;
}
if ($segment === '..') {
array_pop($parts);
} else {
$parts[] = $segment;
}
}
return '/' . implode('/', $parts);
}
$input = '/data/app/storage/link/../link/file.txt';
echo normalizePath($input);
This cleans up the . and .. in the path, but does not resolve the soft link.
During permission control, the original path and realpath() path can be recorded at the same time to make permission comparison:
$originalPath = '/data/app/storage/link/file.txt';
$realPath = realpath($originalPath);
if (strpos($realPath, '/data/app/storage/real/') !== 0) {
die('This path is not allowed');
}
This approach is suitable for dealing with the problem that soft links point to sensitive paths.
Upload directory verification : Check whether the original path is legal before using realpath() and make sure that the path is still within the allowable range after its resolution.
Development environment debugging : There are many soft links used in the deployment environment. Be sure to pay attention to path changes during debugging to avoid bugs caused by inconsistent paths.
Framework development : If you are developing a framework, it is recommended to provide a custom path resolution tool instead of relying directly on realpath() .
PHP's realpath() can indeed bring path uniformity and simplicity when processing soft links, but it may also cause path disconnection due to parsing behavior. For applications with high security and consistency requirements, it is recommended to adopt a more fine-grained path processing strategy based on actual needs, and implement the path analysis logic yourself if necessary to avoid relying solely on realpath() .