Skip to content

Commit 17ba58a

Browse files
committed
Framework\Uri: Improve query parameter handling
1 parent 0a79788 commit 17ba58a

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

system/src/Grav/Framework/Uri/Uri.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ public function withQueryParam($key, $value)
109109
public function getQueryParams()
110110
{
111111
if ($this->queryParams === null) {
112-
parse_str($this->getQuery(), $this->queryParams);
113-
array_map(function($str) { return rawurldecode($str); }, $this->queryParams);
112+
$this->queryParams = UriFactory::parseQuery($this->getQuery(), true);
114113
}
115114

116115
return $this->queryParams;
@@ -122,7 +121,7 @@ public function getQueryParams()
122121
*/
123122
public function withQueryParams(array $params)
124123
{
125-
$query = $params ? http_build_query($params) : '';
124+
$query = UriFactory::buildQuery($params);
126125

127126
return $this->withQuery($query);
128127
}

system/src/Grav/Framework/Uri/UriFactory.php

+43-9
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public static function parseUrlFromEnvironment(array $env)
8080

8181
// Build path.
8282
$request_uri = isset($env['REQUEST_URI']) ? $env['REQUEST_URI'] : '';
83-
$path = rawurldecode(parse_url('http://example.com' . $request_uri, PHP_URL_PATH));
83+
$path = parse_url('http://example.com' . $request_uri, PHP_URL_PATH);
8484

8585
// Build query string.
8686
$query = isset($env['QUERY_STRING']) ? $env['QUERY_STRING'] : '';
@@ -107,24 +107,58 @@ public static function parseUrlFromEnvironment(array $env)
107107
}
108108

109109
/**
110-
* Advanced `parse_url()` method.
110+
* UTF-8 aware parse_url() implementation.
111111
*
112-
* @param string $uri
112+
* @param string $url
113113
* @return array
114114
* @throws \InvalidArgumentException
115115
*/
116-
public static function parseUrl($uri)
116+
public static function parseUrl($url)
117117
{
118-
if (!is_string($uri)) {
119-
throw new \InvalidArgumentException('Uri must be a string');
118+
if (!is_string($url)) {
119+
throw new \InvalidArgumentException('URL must be a string');
120120
}
121121

122-
// Set Uri parts.
123-
$parts = parse_url($uri);
122+
$encodedUrl = preg_replace_callback(
123+
'%[^:/@?&=#]+%u',
124+
function ($matches) { return rawurlencode($matches[0]); },
125+
$url
126+
);
127+
128+
$parts = parse_url($encodedUrl);
124129
if ($parts === false) {
125-
throw new \InvalidArgumentException('Malformed URI: ' . $uri);
130+
throw new \InvalidArgumentException('Malformed URL: ' . $encodedUrl);
126131
}
127132

128133
return $parts;
129134
}
135+
136+
/**
137+
* Parse query string and return it as an array.
138+
*
139+
* @param string $query
140+
* @params bool $decode
141+
* @return mixed
142+
*/
143+
public static function parseQuery($query, $decode = false)
144+
{
145+
parse_str($query, $params);
146+
147+
if ($decode) {
148+
array_map(function($str) { return rawurldecode($str); }, $params);
149+
}
150+
151+
return $params;
152+
}
153+
154+
/**
155+
* Build query string from variables.
156+
*
157+
* @param array $params
158+
* @return string
159+
*/
160+
public static function buildQuery(array $params)
161+
{
162+
return $params ? http_build_query($params, null, ini_get('arg_separator.output'), PHP_QUERY_RFC3986) : '';
163+
}
130164
}

0 commit comments

Comments
 (0)