@@ -12,16 +12,76 @@ final class QueryStringBuilder
12
12
/**
13
13
* Encode a query as a query string according to RFC 3986.
14
14
*
15
+ * Indexed arrays are encoded using empty squared brackets ([]) unlike
16
+ * `http_build_query`.
17
+ *
18
+ * @param mixed $query
19
+ *
20
+ * @return string
21
+ */
22
+ public static function build ($ query )
23
+ {
24
+ if (!\is_array ($ query )) {
25
+ return self ::rawurlencode ($ query );
26
+ }
27
+
28
+ return \implode ('& ' , \array_map (function ($ value , $ key ) {
29
+ return self ::encode ($ value , $ key );
30
+ }, $ query , \array_keys ($ query )));
31
+ }
32
+
33
+ /**
34
+ * Encode a value.
35
+ *
36
+ * @param mixed $query
37
+ * @param string $prefix
38
+ *
39
+ * @return string
40
+ */
41
+ private static function encode ($ query , $ prefix )
42
+ {
43
+ if (!\is_array ($ query )) {
44
+ return self ::rawurlencode ($ prefix ).'= ' .self ::rawurlencode ($ query );
45
+ }
46
+
47
+ $ isList = self ::isList ($ query );
48
+
49
+ return \implode ('& ' , \array_map (function ($ value , $ key ) use ($ prefix , $ isList ) {
50
+ $ prefix = $ isList ? $ prefix .'[] ' : $ prefix .'[ ' .$ key .'] ' ;
51
+
52
+ return self ::encode ($ value , $ prefix );
53
+ }, $ query , \array_keys ($ query )));
54
+ }
55
+
56
+ /**
57
+ * Tell if the given array is a list.
58
+ *
15
59
* @param array $query
16
60
*
61
+ * @return bool
62
+ */
63
+ private static function isList (array $ query )
64
+ {
65
+ if (0 === \count ($ query ) || !isset ($ query [0 ])) {
66
+ return false ;
67
+ }
68
+
69
+ return \array_keys ($ query ) === \range (0 , \count ($ query ) - 1 );
70
+ }
71
+
72
+ /**
73
+ * Encode a value like rawurlencode, but return "0" when false is given.
74
+ *
75
+ * @param mixed $value
76
+ *
17
77
* @return string
18
78
*/
19
- public static function build ( array $ query )
79
+ private static function rawurlencode ( $ value )
20
80
{
21
- if (0 === \count ( $ query ) ) {
22
- return '' ;
81
+ if (false === $ value ) {
82
+ return '0 ' ;
23
83
}
24
84
25
- return \sprintf ( ' ?%s ' , \http_build_query ( $ query , '' , ' & ' , \ PHP_QUERY_RFC3986 ) );
85
+ return \rawurlencode (( string ) $ value );
26
86
}
27
87
}
0 commit comments