| Total Complexity | 42 |
| Total Lines | 292 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like Environment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Environment, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 64 | final class Environment |
||
| 65 | { |
||
| 66 | /** |
||
| 67 | * requestMethod() |
||
| 68 | * |
||
| 69 | * Gets the request method. |
||
| 70 | * |
||
| 71 | * @return string |
||
| 72 | */ |
||
| 73 | public static function requestMethod(): string |
||
| 74 | { |
||
| 75 | /** @var string $method */ |
||
| 76 | $method = ( |
||
| 77 | Environment::var('HTTP_X_HTTP_METHOD_OVERRIDE', Environment::var('REQUEST_METHOD', 'GET')) |
||
| 78 | ); |
||
| 79 | return Strings::upper($method); |
||
| 80 | } |
||
| 81 | |||
| 82 | /** |
||
| 83 | * var() |
||
| 84 | * |
||
| 85 | * Gets a variable from $_SERVER using $default if not provided. |
||
| 86 | * |
||
| 87 | * @param string $var Variable name. |
||
| 88 | * @param string|int|null $default Default value to substitute. |
||
| 89 | * @return string|int|null |
||
| 90 | */ |
||
| 91 | public static function var(string $var, string | int | null $default = ''): string | int | null |
||
| 92 | { |
||
| 93 | /** @var string|int|null $value */ |
||
| 94 | $value = Arrays::get($_SERVER, $var) ?? $default; |
||
| 95 | |||
| 96 | return $value; |
||
| 97 | } |
||
| 98 | |||
| 99 | /** |
||
| 100 | * ipAddress() |
||
| 101 | * |
||
| 102 | * Return the visitor's IP address. |
||
| 103 | * |
||
| 104 | * @param bool $trustProxy Whether to trust HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR. |
||
| 105 | * @return string |
||
| 106 | */ |
||
| 107 | public static function ipAddress(bool $trustProxy = false): string |
||
| 108 | { |
||
| 109 | // Pretty self-explanatory. Try to get an 'accurate' IP |
||
| 110 | $cloudflare = Environment::var('HTTP_CF_CONNECTING_IP'); |
||
| 111 | |||
| 112 | if ($cloudflare !== '') { |
||
| 113 | Arrays::set($_SERVER, 'REMOTE_ADDR', $cloudflare); |
||
| 114 | } |
||
| 115 | |||
| 116 | if (!$trustProxy) { |
||
| 117 | /** @var string */ |
||
| 118 | return Environment::var('REMOTE_ADDR'); |
||
| 119 | } |
||
| 120 | |||
| 121 | $ip = ''; |
||
| 122 | $ips = []; |
||
| 123 | |||
| 124 | /** @var string $forwarded */ |
||
| 125 | $forwarded = Environment::var('HTTP_X_FORWARDED_FOR'); |
||
| 126 | /** @var string $realip */ |
||
| 127 | $realip = Environment::var('HTTP_X_REAL_IP'); |
||
| 128 | |||
| 129 | if ($forwarded !== '') { |
||
| 130 | /** @var list<string> $ips */ |
||
| 131 | $ips = explode(',', $forwarded); |
||
| 132 | } elseif ($realip !== '') { |
||
| 133 | /** @var list<string> $ips */ |
||
| 134 | $ips = explode(',', $realip); |
||
| 135 | } |
||
| 136 | |||
| 137 | /** @var list<string> $ips */ |
||
| 138 | $ips = Arrays::mapDeep($ips, 'trim'); |
||
| 139 | |||
| 140 | if (count($ips) > 0) { |
||
| 141 | foreach ($ips as $val) { |
||
| 142 | // @phpstan-ignore-next-line |
||
| 143 | if (inet_ntop(inet_pton($val)) === $val && Environment::isPublicIp($val)) { |
||
| 144 | /** @var string $ip */ |
||
| 145 | $ip = $val; |
||
| 146 | break; |
||
| 147 | } |
||
| 148 | } |
||
| 149 | } |
||
| 150 | unset($ips); |
||
| 151 | |||
| 152 | if ($ip === '') { |
||
| 153 | /** @var string $ip */ |
||
| 154 | $ip = Environment::var('HTTP_CLIENT_IP', Environment::var('REMOTE_ADDR')); |
||
| 155 | } |
||
| 156 | return $ip; |
||
| 157 | } |
||
| 158 | |||
| 159 | /** |
||
| 160 | * isPrivateIp() |
||
| 161 | * |
||
| 162 | * Determines if an IP address is within the private range. |
||
| 163 | * |
||
| 164 | * @param string $ipaddress IP address to check. |
||
| 165 | * @return bool |
||
| 166 | */ |
||
| 167 | public static function isPrivateIp(string $ipaddress): bool |
||
| 173 | ); |
||
| 174 | } |
||
| 175 | |||
| 176 | /** |
||
| 177 | * isReservedIp() |
||
| 178 | * |
||
| 179 | * Determines if an IP address is within the reserved range. |
||
| 180 | * |
||
| 181 | * @param string $ipaddress IP address to check. |
||
| 182 | * @return bool |
||
| 183 | */ |
||
| 184 | public static function isReservedIp(string $ipaddress): bool |
||
| 185 | { |
||
| 186 | return !(bool) filter_var( |
||
| 187 | $ipaddress, |
||
| 188 | FILTER_VALIDATE_IP, |
||
| 189 | FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE |
||
| 190 | ); |
||
| 191 | } |
||
| 192 | |||
| 193 | /** |
||
| 194 | * isPublicIp() |
||
| 195 | * |
||
| 196 | * Determines if an IP address is not within the private or reserved ranges. |
||
| 197 | * |
||
| 198 | * @param string $ipaddress IP address to check. |
||
| 199 | * @return bool |
||
| 200 | */ |
||
| 201 | public static function isPublicIp(string $ipaddress): bool |
||
| 202 | { |
||
| 203 | return (!Environment::isPrivateIp($ipaddress) && !Environment::isReservedIp($ipaddress)); |
||
| 204 | } |
||
| 205 | |||
| 206 | /** |
||
| 207 | * host() |
||
| 208 | * |
||
| 209 | * Determines current hostname. |
||
| 210 | * |
||
| 211 | * @param bool $stripWww True to strip www. off the host, false to leave it be. |
||
| 212 | * @param bool $acceptForwarded True to accept, false otherwise. |
||
| 213 | * @return string |
||
| 214 | */ |
||
| 215 | public static function host(bool $stripWww = false, bool $acceptForwarded = false): string |
||
| 235 | } |
||
| 236 | |||
| 237 | /** |
||
| 238 | * isHttps() |
||
| 239 | * |
||
| 240 | * Checks to see if SSL is in use. |
||
| 241 | * |
||
| 242 | * @return bool |
||
| 243 | */ |
||
| 244 | public static function isHttps(): bool |
||
| 245 | { |
||
| 246 | $headers = \getallheaders(); |
||
| 247 | |||
| 248 | $server = Environment::var('HTTPS'); |
||
| 249 | $frontEnd = Arrays::get($headers, 'X-Forwarded-Proto', ''); |
||
|
1 ignored issue
–
show
|
|||
| 250 | $forwarded = Arrays::get($headers, 'Front-End-Https', ''); |
||
| 251 | |||
| 252 | if ($server !== 'off' && $server !== '') { |
||
| 253 | return true; |
||
| 254 | } |
||
| 255 | return $forwarded === 'https' || ($frontEnd !== '' && $frontEnd !== 'off'); |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * url() |
||
| 260 | * |
||
| 261 | * Retrieve the current URL. |
||
| 262 | * |
||
| 263 | * @return string |
||
| 264 | */ |
||
| 265 | public static function url(): string |
||
| 297 | } |
||
| 298 | |||
| 299 | /** |
||
| 300 | * iniGet() |
||
| 301 | * |
||
| 302 | * Safe ini_get taking into account its availability. |
||
| 303 | * |
||
| 304 | * @param string $option The configuration option name. |
||
| 305 | * @param bool $standardize Standardize returned values to 1 or 0? |
||
| 306 | * @return string |
||
| 307 | * |
||
| 308 | * @throws RuntimeException|ArgumentCountError |
||
| 309 | */ |
||
| 310 | public static function iniGet(string $option, bool $standardize = false): string |
||
| 311 | { |
||
| 312 | // @codeCoverageIgnoreStart |
||
| 313 | if (!function_exists('ini_get')) { |
||
| 314 | // disabled_functions? |
||
| 315 | throw new RuntimeException('Native ini_get function not available.'); |
||
| 316 | } |
||
| 317 | // @codeCoverageIgnoreEnd |
||
| 318 | $value = ini_get($option); |
||
| 319 | |||
| 320 | if ($value === false) { |
||
| 321 | throw new RuntimeException('$option does not exist.'); |
||
| 322 | } |
||
| 323 | |||
| 324 | $value = trim($value); |
||
| 325 | |||
| 326 | if ($standardize) { |
||
| 327 | return match (Strings::lower($value)) { |
||
| 328 | 'yes', 'on', 'true', '1' => '1', |
||
| 329 | 'no', 'off', 'false', '0' => '0', |
||
| 330 | default => $value |
||
| 331 | }; |
||
| 332 | } |
||
| 333 | return $value; |
||
| 334 | } |
||
| 335 | |||
| 336 | /** |
||
| 337 | * iniSet() |
||
| 338 | * |
||
| 339 | * Safe ini_set taking into account its availability. |
||
| 340 | * |
||
| 341 | * @param string $option The configuration option name. |
||
| 342 | * @param string|int|float|bool|null $value The new value for the option. |
||
| 343 | * @return string|false |
||
| 344 | * |
||
| 345 | * @throws RuntimeException|ArgumentCountError |
||
| 346 | */ |
||
| 347 | public static function iniSet(string $option, string|int|float|bool|null $value): string | false |
||
| 356 | } |
||
| 357 | } |
||
| 358 |