PHP realpath() not working, returns empty string

PHP’s useful realpath() can cause problems when it returns an empty string. Realpath is typically used to “clean up” a path, but if you pass in a nonexistent path, it’ll return FALSE. I created a bug in  my code when I used realpath to “clean up” a string that was a path.

The following code is broken, but you won’t notice the effect if $targetPath is a valid path. Your code breaks if $targetPath is a nonexistent path.

$targetPath = realpath($targetPath);
if (!is_dir($targetPath)) {
  mkdir($targetPath);
}

That code might look okay: clean up the path, and then make sure that the directory exists. It’s broken because, when the $targetPath doesn’t exist, $targetPath is set to FALSE, and mkdir(FALSE) throws a warning.

The corrected code is:

if (!is_dir($targetPath)) {
  mkdir($targetPath);
}
$targetPath = realpath($targetPath);

You let the OS resolve the path, and then use realpath() afterward, to clean up the path. (This also isn’t the best way to do this. It’s better to build up the target path with a directory and a filename, and test the directory with realpath(), and sanitize the filename.)

I was bitten by this gotcha when I assumed that realpath() was a tool to clean up the path string, rather than a tool to examine the filesystem and resolve dots and symlinks. Realpath() also fails if your process doesn’t have permission to look at all the directories in the path.

I added realpath into the code near the top of the function, bypassing checks for file existence.

So, it’s useful when you are working with files, but not really quite as useful when you’re building up file paths in strings.


Leave a Reply