How can I determine if a file path is absolute? Must work on both Windows and Linux.
Asked
Active
Viewed 5,667 times
7
-
Check if it has a colon `:`? Paths the begin with `http://`, `https://`, `file:///`, `C:/` are all absolute. You can also see if the path begins with `/` or `~`. – Logan Murphy May 09 '14 at 17:06
-
@LoganMurphy Unix doesn't – xd6_ May 09 '14 at 17:07
-
you read this, maybe is useful? http://stackoverflow.com/questions/7392274/checking-for-relative-vs-absolute-paths-urls-in-php – Gonzalo Bahamondez May 09 '14 at 17:09
-
@xd6_ Unix doesn't what? – Logan Murphy May 09 '14 at 17:12
-
1@LoganMurphy sorry, Unix/linux don't use colon in paths the question requires linux compatability also – xd6_ May 09 '14 at 17:17
2 Answers
7
Here my try at doing it with a single function:
function isAbsolutePath($path) {
if (!is_string($path)) {
$mess = sprintf('String expected but was given %s', gettype($path));
throw new \InvalidArgumentException($mess);
}
if (!ctype_print($path)) {
$mess = 'Path can NOT have non-printable characters or be empty';
throw new \DomainException($mess);
}
// Optional wrapper(s).
$regExp = '%^(?<wrappers>(?:[[:print:]]{2,}://)*)';
// Optional root prefix.
$regExp .= '(?<root>(?:[[:alpha:]]:/|/)?)';
// Actual path.
$regExp .= '(?<path>(?:[[:print:]]*))$%';
$parts = [];
if (!preg_match($regExp, $path, $parts)) {
$mess = sprintf('Path is NOT valid, was given %s', $path);
throw new \DomainException($mess);
}
if ('' !== $parts['root']) {
return true;
}
return false;
}
I took this from one of my project you might find useful while working with files and paths: dragonrun1/file_path_normalizer

Dragonaire
- 313
- 3
- 7
-
1
-
This is a solution to copypaste from a StackOverflow answer. What I would be more interested in is whether there is currently a "winning" or "de facto standard" solution that has established existence outside StackOverflow, like a library that can be installed with composer or something. Is there a "de facto standard" path utilities library? – Szczepan Hołyszewski Dec 29 '17 at 14:09
-
If you look at my answer above I give link to the project I did which is also available through composer. – Dragonaire Jan 02 '18 at 18:27
-
I had trouble with this on Windows - I had to change the root capture group to look allow for backslashes instead of only forward slashes. Old: `$regExp .= '(?
(?:[[:alpha:]]:/|/)?)';` New:`(? – HPierce Sep 03 '18 at 00:08(?:[[:alpha:]]:[/\\\\]|/)`. Note the use of _4_ backslashes, the first and third are doing PHP level escaping, the second is doing regex level escaping. -
If you look at the latest version from my library you'll find I've changed that method a lot and just replace all back-slashes with forward-slashes to start with in the path since windows also allows them. – Dragonaire Sep 05 '18 at 20:19
-
@HPierce, i have copied the entire function and added you fix, but I got a regex error, namely: "missing closing parenthesis at offset". So I have added a little at the end and got it working. Old regex: `(?
(?:[[:alpha:]]:[/\\\\]|/)` new: `(? – Pakspul Jun 20 '22 at 17:06(?:[[:alpha:]]:[/\\\\]|/)?)`. See the `?)` at the end.
5
Here's what I've come up with:
function is_absolute_path($path) {
if($path === null || $path === '') throw new Exception("Empty path");
return $path[0] === DIRECTORY_SEPARATOR || preg_match('~\A[A-Z]:(?![^/\\\\])~i',$path) > 0;
}
I think that covers all the possible root paths for Windows.
-
1It still breaks for paths that have [wrappers](http://php.net/manual/en/wrappers.php). try 'zlib://c:/dummy/path/' or 'file://c:/dummy/path' – Dragonaire Jun 24 '16 at 21:16
-
@Dragonaire [Node](https://nodejs.org/api/path.html#path_path_isabsolute_path) returns `false` for both those examples too, which I think is the correct answer. We're talking about *file* paths here, not URLs. – mpen Jun 24 '16 at 21:51
-
Guess you need to read the wrapper link I give as they have nothing to do with URLs in and of themselves. You can use them to implement things like ftp around a stream but then you have file:// which does no more then make a local file in a stream resource instead of just a string. The fact that Node(JS) doesn't understand something that is PHP specific doesn't surprise me either ;) – Dragonaire Jun 25 '16 at 22:33
-
@Dragonaire Yes, but that's not the point. It depends on your use case. If I'm accepting file paths from a user, for example, do I want to allow them specify wrapper methods? Probably not. – mpen Jun 27 '16 at 15:44
-
That's one reason I add the option to not allow them in my little library ;) – Dragonaire Jun 28 '16 at 16:24