-
-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathPathResolver.php
More file actions
88 lines (76 loc) · 2.97 KB
/
PathResolver.php
File metadata and controls
88 lines (76 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php
declare(strict_types=1);
/*
* Go! AOP framework
*
* @copyright Copyright 2014, Lisachenko Alexander <lisachenko.it@gmail.com>
*
* This source file is subject to the license that is bundled
* with this source code in the file LICENSE.
*/
namespace Go\ParserReflection\Instrument;
/**
* Special class for resolving path for different file systems, wrappers, etc
*
* @see http://stackoverflow.com/questions/4049856/replace-phps-realpath/4050444
* @see http://bugs.php.net/bug.php?id=52769
*
* @link https://github.com/goaop/framework/blob/master/src/Instrument/PathResolver.php
*/
class PathResolver
{
/**
* Custom replacement for realpath() and stream_resolve_include_path()
*
* @param string|array<int, string> $somePath Path without normalization or array of paths
* @param bool $shouldCheckExistence Flag for checking existence of resolved filename
*
* @return ($somePath is array ? array<int, string|false> : string|false)
*/
public static function realpath($somePath, $shouldCheckExistence = false)
{
// Do not resolve empty string/false/arrays into the current path
if (!$somePath) {
return $somePath;
}
if (is_array($somePath)) {
return array_map([__CLASS__, __FUNCTION__], $somePath);
}
// Trick to get scheme name and path in one action. If no scheme, then there will be only one part
$components = explode('://', $somePath, 2);
[$pathScheme, $path] = isset($components[1]) ? $components : [null, $components[0]];
// Optimization to bypass complex logic for simple paths (eg. not in phar archives)
if (!$pathScheme && ($fastPath = stream_resolve_include_path($somePath))) {
return $fastPath;
}
$isWindowsAbsolutePath = $path !== null && strlen($path) > 1 && preg_match('/^[A-Za-z]:/', $path) === 1;
$isRelative = !$pathScheme && $path !== null && !str_starts_with($path, '/') && !$isWindowsAbsolutePath;
if ($isRelative) {
$path = getcwd() . DIRECTORY_SEPARATOR . $path;
}
// resolve path parts (single dot, double dot and double delimiters)
$path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path ?? '');
if (strpos($path, '.') !== false) {
$parts = explode(DIRECTORY_SEPARATOR, $path);
$absolutes = [];
foreach ($parts as $part) {
if ('.' === $part) {
continue;
}
if ('..' === $part) {
array_pop($absolutes);
} else {
$absolutes[] = $part;
}
}
$path = implode(DIRECTORY_SEPARATOR, $absolutes);
}
if ($pathScheme) {
$path = "{$pathScheme}://{$path}";
}
if ($shouldCheckExistence && !file_exists($path)) {
return false;
}
return $path;
}
}