1<?php 2 3/** 4 * @see https://github.com/laminas/laminas-diactoros for the canonical source repository 5 * @copyright https://github.com/laminas/laminas-diactoros/blob/master/COPYRIGHT.md 6 * @license https://github.com/laminas/laminas-diactoros/blob/master/LICENSE.md New BSD License 7 */ 8 9namespace Laminas\Diactoros; 10 11use InvalidArgumentException; 12use Psr\Http\Message\UploadedFileInterface; 13use stdClass; 14use UnexpectedValueException; 15 16use function array_change_key_case; 17use function array_key_exists; 18use function explode; 19use function implode; 20use function is_array; 21use function is_callable; 22use function strtolower; 23 24use const CASE_LOWER; 25 26/** 27 * Class for marshaling a request object from the current PHP environment. 28 * 29 * Logic largely refactored from the Laminas Laminas\Http\PhpEnvironment\Request class. 30 * 31 * @copyright Copyright (c) 2005-2015 Laminas (https://www.zend.com) 32 * @license https://getlaminas.org/license/new-bsd New BSD License 33 */ 34abstract class ServerRequestFactory 35{ 36 /** 37 * Function to use to get apache request headers; present only to simplify mocking. 38 * 39 * @var callable 40 */ 41 private static $apacheRequestHeaders = 'apache_request_headers'; 42 43 /** 44 * Create a request from the supplied superglobal values. 45 * 46 * If any argument is not supplied, the corresponding superglobal value will 47 * be used. 48 * 49 * The ServerRequest created is then passed to the fromServer() method in 50 * order to marshal the request URI and headers. 51 * 52 * @see fromServer() 53 * @param array $server $_SERVER superglobal 54 * @param array $query $_GET superglobal 55 * @param array $body $_POST superglobal 56 * @param array $cookies $_COOKIE superglobal 57 * @param array $files $_FILES superglobal 58 * @return ServerRequest 59 * @throws InvalidArgumentException for invalid file values 60 */ 61 public static function fromGlobals( 62 array $server = null, 63 array $query = null, 64 array $body = null, 65 array $cookies = null, 66 array $files = null 67 ) { 68 $server = normalizeServer( 69 $server ?: $_SERVER, 70 is_callable(self::$apacheRequestHeaders) ? self::$apacheRequestHeaders : null 71 ); 72 $files = normalizeUploadedFiles($files ?: $_FILES); 73 $headers = marshalHeadersFromSapi($server); 74 75 if (null === $cookies && array_key_exists('cookie', $headers)) { 76 $cookies = parseCookieHeader($headers['cookie']); 77 } 78 79 return new ServerRequest( 80 $server, 81 $files, 82 marshalUriFromSapi($server, $headers), 83 marshalMethodFromSapi($server), 84 'php://input', 85 $headers, 86 $cookies ?: $_COOKIE, 87 $query ?: $_GET, 88 $body ?: $_POST, 89 marshalProtocolVersionFromSapi($server) 90 ); 91 } 92 93 /** 94 * Access a value in an array, returning a default value if not found 95 * 96 * @deprecated since 1.8.0; no longer used internally. 97 * @param string $key 98 * @param array $values 99 * @param mixed $default 100 * @return mixed 101 */ 102 public static function get($key, array $values, $default = null) 103 { 104 if (array_key_exists($key, $values)) { 105 return $values[$key]; 106 } 107 108 return $default; 109 } 110 111 /** 112 * Search for a header value. 113 * 114 * Does a case-insensitive search for a matching header. 115 * 116 * If found, it is returned as a string, using comma concatenation. 117 * 118 * If not, the $default is returned. 119 * 120 * @deprecated since 1.8.0; no longer used internally. 121 * @param string $header 122 * @param array $headers 123 * @param mixed $default 124 * @return string 125 */ 126 public static function getHeader($header, array $headers, $default = null) 127 { 128 $header = strtolower($header); 129 $headers = array_change_key_case($headers, CASE_LOWER); 130 if (array_key_exists($header, $headers)) { 131 $value = is_array($headers[$header]) ? implode(', ', $headers[$header]) : $headers[$header]; 132 return $value; 133 } 134 135 return $default; 136 } 137 138 /** 139 * Marshal the $_SERVER array 140 * 141 * Pre-processes and returns the $_SERVER superglobal. 142 * 143 * @deprected since 1.8.0; use Laminas\Diactoros\normalizeServer() instead. 144 * @param array $server 145 * @return array 146 */ 147 public static function normalizeServer(array $server) 148 { 149 return normalizeServer( 150 $server ?: $_SERVER, 151 is_callable(self::$apacheRequestHeaders) ? self::$apacheRequestHeaders : null 152 ); 153 } 154 155 /** 156 * Normalize uploaded files 157 * 158 * Transforms each value into an UploadedFileInterface instance, and ensures 159 * that nested arrays are normalized. 160 * 161 * @deprecated since 1.8.0; use \Laminas\Diactoros\normalizeUploadedFiles instead. 162 * @param array $files 163 * @return array 164 * @throws InvalidArgumentException for unrecognized values 165 */ 166 public static function normalizeFiles(array $files) 167 { 168 return normalizeUploadedFiles($files); 169 } 170 171 /** 172 * Marshal headers from $_SERVER 173 * 174 * @deprecated since 1.8.0; use Laminas\Diactoros\marshalHeadersFromSapi(). 175 * @param array $server 176 * @return array 177 */ 178 public static function marshalHeaders(array $server) 179 { 180 return marshalHeadersFromSapi($server); 181 } 182 183 /** 184 * Marshal the URI from the $_SERVER array and headers 185 * 186 * @deprecated since 1.8.0; use Laminas\Diactoros\marshalUriFromSapi() instead. 187 * @param array $server 188 * @param array $headers 189 * @return Uri 190 */ 191 public static function marshalUriFromServer(array $server, array $headers) 192 { 193 return marshalUriFromSapi($server, $headers); 194 } 195 196 /** 197 * Marshal the host and port from HTTP headers and/or the PHP environment 198 * 199 * @deprecated since 1.8.0; use Laminas\Diactoros\marshalUriFromSapi() instead, 200 * and pull the host and port from the Uri instance that function 201 * returns. 202 * @param stdClass $accumulator 203 * @param array $server 204 * @param array $headers 205 */ 206 public static function marshalHostAndPortFromHeaders(stdClass $accumulator, array $server, array $headers) 207 { 208 $uri = marshalUriFromSapi($server, $headers); 209 $accumulator->host = $uri->getHost(); 210 $accumulator->port = $uri->getPort(); 211 } 212 213 /** 214 * Detect the base URI for the request 215 * 216 * Looks at a variety of criteria in order to attempt to autodetect a base 217 * URI, including rewrite URIs, proxy URIs, etc. 218 * 219 * @deprecated since 1.8.0; use Laminas\Diactoros\marshalUriFromSapi() instead, 220 * and pull the path from the Uri instance that function returns. 221 * @param array $server 222 * @return string 223 */ 224 public static function marshalRequestUri(array $server) 225 { 226 $uri = marshalUriFromSapi($server, []); 227 return $uri->getPath(); 228 } 229 230 /** 231 * Strip the query string from a path 232 * 233 * @deprecated since 1.8.0; no longer used internally. 234 * @param mixed $path 235 * @return string 236 */ 237 public static function stripQueryString($path) 238 { 239 return explode('?', $path, 2)[0]; 240 } 241} 242