@@ -12,16 +12,76 @@ final class QueryStringBuilder
1212 /**
1313 * Encode a query as a query string according to RFC 3986.
1414 *
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+ *
1559 * @param array $query
1660 *
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+ *
1777 * @return string
1878 */
19- public static function build ( array $ query )
79+ private static function rawurlencode ( $ value )
2080 {
21- if (0 === \count ( $ query ) ) {
22- return '' ;
81+ if (false === $ value ) {
82+ return '0 ' ;
2383 }
2484
25- return \sprintf ( ' ?%s ' , \http_build_query ( $ query , '' , ' & ' , \ PHP_QUERY_RFC3986 ) );
85+ return \rawurlencode (( string ) $ value );
2686 }
2787}
0 commit comments