|
1
|
|
|
<?php |
|
2
|
|
|
declare(strict_types=1); |
|
3
|
|
|
|
|
4
|
|
|
namespace Selami\Stdlib; |
|
5
|
|
|
|
|
6
|
|
|
class BaseUrlExtractor |
|
7
|
|
|
{ |
|
8
|
|
|
public static function getBaseUrl(array $httpServerData) : string |
|
9
|
|
|
{ |
|
10
|
|
|
$protocol = self::getProtocol($httpServerData); |
|
11
|
|
|
$host = self::getHost($httpServerData); |
|
12
|
|
|
$uriPath = $httpServerData['REQUEST_URI'] ?? ''; |
|
13
|
|
|
$filename = $httpServerData['SCRIPT_FILENAME'] ?? ''; |
|
14
|
|
|
$scriptName = $httpServerData['SCRIPT_NAME']; |
|
15
|
|
|
$phpSelf = $httpServerData['PHP_SELF']; |
|
16
|
|
|
$origScriptName = $httpServerData['ORIG_SCRIPT_NAME'] ?? ''; |
|
17
|
|
|
$baseUrl = self::getRelativeBaseUrl($scriptName, $phpSelf, $filename, $origScriptName); |
|
18
|
|
|
return trim(self::determineFullBaseUrl($baseUrl, $protocol, $host, $uriPath), '/'); |
|
19
|
|
|
} |
|
20
|
|
|
|
|
21
|
|
|
public static function determineFullBaseUrl($baseUrl, $protocol, $host, $uriPath): string |
|
22
|
|
|
{ |
|
23
|
|
|
// If the baseUrl is empty, then ply return it |
|
24
|
|
|
if (empty($baseUrl)) { |
|
25
|
|
|
return $protocol . '://' . $host.''; |
|
26
|
|
|
} |
|
27
|
|
|
// Full base URL matches. |
|
28
|
|
|
if (0 === strpos($uriPath, $baseUrl)) { |
|
29
|
|
|
return $protocol . '://' . $host.$baseUrl; |
|
30
|
|
|
} |
|
31
|
|
|
// Directory portion of base path matches. |
|
32
|
|
|
$baseDir = str_replace('\\', '/', dirname($baseUrl)); |
|
33
|
|
|
if (0 === strpos($uriPath, $baseDir)) { |
|
34
|
|
|
return $protocol . '://' . $host.$baseDir; |
|
35
|
|
|
} |
|
36
|
|
|
$basename = basename($baseUrl); |
|
37
|
|
|
// No match whatsoever |
|
38
|
|
|
if (empty($basename) || false === strpos($uriPath, $basename)) { |
|
39
|
|
|
return $protocol . '://' . $host; |
|
40
|
|
|
} |
|
41
|
|
|
// If using mod_rewrite or ISAPI_Rewrite strip the script filename |
|
42
|
|
|
// out of the base path. $pos !== 0 makes sure it is not matching a |
|
43
|
|
|
// value from PATH_INFO or QUERY_STRING. |
|
44
|
|
|
if ((false !== ($pos = strpos($uriPath, $baseUrl)) && $pos !== 0) && strlen($uriPath) >= strlen($baseUrl) |
|
45
|
|
|
) { |
|
46
|
|
|
$baseUrl = substr($uriPath, 0, $pos + strlen($baseUrl)); |
|
47
|
|
|
} |
|
48
|
|
|
return trim($protocol . '://' . $host .$baseUrl, '/'); |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
|
|
|
|
52
|
|
|
public static function getProtocol(array $httpServerData) : string |
|
53
|
|
|
{ |
|
54
|
|
|
return isset($httpServerData['HTTPS']) && $httpServerData['HTTPS'] !== 'Off' ? 'https': 'http'; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
public static function getHost($httpServerData) : string |
|
58
|
|
|
{ |
|
59
|
|
|
return $httpServerData['HTTP_HOST']; |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
public static function getRelativeBaseUrl($scriptName, $phpSelf, $filename, $origScriptName) : string |
|
63
|
|
|
{ |
|
64
|
|
|
if ($scriptName !== null && basename($scriptName) === $filename) { |
|
65
|
|
|
return $scriptName; |
|
66
|
|
|
} |
|
67
|
|
|
if ($phpSelf !== null && basename($phpSelf) === $filename) { |
|
68
|
|
|
return $phpSelf; |
|
69
|
|
|
} |
|
70
|
|
|
if ($origScriptName !== null && basename($origScriptName) === $filename) { |
|
71
|
|
|
// 1and1 shared hosting compatibility. |
|
72
|
|
|
return $origScriptName; |
|
73
|
|
|
} |
|
74
|
|
|
// Backtrack up the SCRIPT_FILENAME to find the portion |
|
75
|
|
|
// matching PHP_SELF. |
|
76
|
|
|
$baseUrl = '/'; |
|
77
|
|
|
$basename = basename($filename); |
|
78
|
|
|
if ($basename) { |
|
79
|
|
|
$path = ($phpSelf ? trim($phpSelf, '/') : ''); |
|
80
|
|
|
$basePos = strpos($path, $basename) ?: 0; |
|
81
|
|
|
$baseUrl .= substr($path, 0, $basePos) . $basename; |
|
82
|
|
|
} |
|
83
|
|
|
return $baseUrl; |
|
84
|
|
|
} |
|
85
|
|
|
} |
|
86
|
|
|
|