1<?php 2 3namespace GuzzleHttp\Psr7; 4 5final class Query 6{ 7 /** 8 * Parse a query string into an associative array. 9 * 10 * If multiple values are found for the same key, the value of that key 11 * value pair will become an array. This function does not parse nested 12 * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` 13 * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`. 14 * 15 * @param string $str Query string to parse 16 * @param int|bool $urlEncoding How the query string is encoded 17 * 18 * @return array 19 */ 20 public static function parse($str, $urlEncoding = true) 21 { 22 $result = []; 23 24 if ($str === '') { 25 return $result; 26 } 27 28 if ($urlEncoding === true) { 29 $decoder = function ($value) { 30 return rawurldecode(str_replace('+', ' ', $value)); 31 }; 32 } elseif ($urlEncoding === PHP_QUERY_RFC3986) { 33 $decoder = 'rawurldecode'; 34 } elseif ($urlEncoding === PHP_QUERY_RFC1738) { 35 $decoder = 'urldecode'; 36 } else { 37 $decoder = function ($str) { 38 return $str; 39 }; 40 } 41 42 foreach (explode('&', $str) as $kvp) { 43 $parts = explode('=', $kvp, 2); 44 $key = $decoder($parts[0]); 45 $value = isset($parts[1]) ? $decoder($parts[1]) : null; 46 if (!isset($result[$key])) { 47 $result[$key] = $value; 48 } else { 49 if (!is_array($result[$key])) { 50 $result[$key] = [$result[$key]]; 51 } 52 $result[$key][] = $value; 53 } 54 } 55 56 return $result; 57 } 58 59 /** 60 * Build a query string from an array of key value pairs. 61 * 62 * This function can use the return value of `parse()` to build a query 63 * string. This function does not modify the provided keys when an array is 64 * encountered (like `http_build_query()` would). 65 * 66 * @param array $params Query string parameters. 67 * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 68 * to encode using RFC3986, or PHP_QUERY_RFC1738 69 * to encode using RFC1738. 70 * 71 * @return string 72 */ 73 public static function build(array $params, $encoding = PHP_QUERY_RFC3986) 74 { 75 if (!$params) { 76 return ''; 77 } 78 79 if ($encoding === false) { 80 $encoder = function ($str) { 81 return $str; 82 }; 83 } elseif ($encoding === PHP_QUERY_RFC3986) { 84 $encoder = 'rawurlencode'; 85 } elseif ($encoding === PHP_QUERY_RFC1738) { 86 $encoder = 'urlencode'; 87 } else { 88 throw new \InvalidArgumentException('Invalid type'); 89 } 90 91 $qs = ''; 92 foreach ($params as $k => $v) { 93 $k = $encoder($k); 94 if (!is_array($v)) { 95 $qs .= $k; 96 if ($v !== null) { 97 $qs .= '=' . $encoder($v); 98 } 99 $qs .= '&'; 100 } else { 101 foreach ($v as $vv) { 102 $qs .= $k; 103 if ($vv !== null) { 104 $qs .= '=' . $encoder($vv); 105 } 106 $qs .= '&'; 107 } 108 } 109 } 110 111 return $qs ? (string) substr($qs, 0, -1) : ''; 112 } 113} 114