Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2890792
PhutilQueryStringParser.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
3 KB
Referenced Files
None
Subscribers
None
PhutilQueryStringParser.php
View Options
<?php
/**
* Utilities for parsing HTTP query strings.
*
* The builtin functions in PHP (notably, `parse_str()` and automatic parsing
* prior to request handling) are not suitable in the general case because they
* silently convert some characters in parameter names into underscores.
*
* For example, if you call `parse_str()` with input like this:
*
* x.y=z
*
* ...the output is this:
*
* array(
* 'x_y' => 'z',
* );
*
* ...with the `.` replaced with an underscore, `_`. Other characters converted
* in this way include space and unmatched opening brackets.
*
* Broadly, this is part of the terrible legacy of `register_globals`. Since
* we'd like to be able to parse all valid query strings without destroying any
* data, this class implements a less-encumbered parser.
*/
final
class
PhutilQueryStringParser
extends
Phobject
{
/**
* Parses a query string into a dictionary, applying PHP rules for handling
* array nomenclature (like `a[]=1`) in parameter names.
*
* For a more basic parse, see @{method:parseQueryStringToPairList}.
*
* @param string Query string.
* @return map<string, wild> Parsed dictionary.
*/
public
function
parseQueryString
(
$query_string
)
{
$result
=
array
(
)
;
$list
=
$this
->
parseQueryStringToPairList
(
$query_string
)
;
foreach
(
$list
as
$parts
)
{
list
(
$key
,
$value
)
=
$parts
;
if
(
!
strlen
(
$key
)
)
{
continue
;
}
$this
->
parseQueryKeyToArr
(
$key
,
$value
,
$result
)
;
}
return
$result
;
}
/**
* Parses a query string into a basic list of pairs, without handling any
* array information in the keys. For example:
*
* a[]=1&a[]=2
*
* ...will parse into:
*
* array(
* array('a[]', '1'),
* array('a[]', '2'),
* );
*
* Use @{method:parseQueryString} to produce a more sophisticated parse which
* applies array rules and returns a dictionary.
*
* @param string Query string.
* @return list<pair<string, string>> List of parsed parameters.
*/
public
function
parseQueryStringToPairList
(
$query_string
)
{
$list
=
array
(
)
;
if
(
!
strlen
(
$query_string
)
)
{
return
$list
;
}
$pairs
=
explode
(
'&'
,
$query_string
)
;
foreach
(
$pairs
as
$pair
)
{
if
(
!
strlen
(
$pair
)
)
{
continue
;
}
$parts
=
explode
(
'='
,
$pair
,
2
)
;
if
(
count
(
$parts
)
<
2
)
{
$parts
[
]
=
''
;
}
$list
[
]
=
array
(
urldecode
(
$parts
[
0
]
)
,
urldecode
(
$parts
[
1
]
)
,
)
;
}
return
$list
;
}
/**
* Treats the key as a flat query that potentially has square brackets. If
* there are square brackets we parse them into an array.
*
* Example input:
* $key = "email[0]";
* $val = "my@example.com";
*
* Example output:
* array("email" => array(0 => "my@example.com"));
*
* @param string $key
* @param string $val
* @param array $input_arr
*/
private
function
parseQueryKeyToArr
(
$key
,
$val
,
array
&
$input_arr
)
{
if
(
preg_match
(
'/^[^\[\]]+(?:\[[^\[\]]*\])+$/'
,
$key
)
)
{
$key_pieces
=
preg_split
(
'/\]?\[/'
,
rtrim
(
$key
,
']'
)
)
;
if
(
$key_pieces
)
{
$cursor
=
&
$input_arr
;
foreach
(
$key_pieces
as
$piece
)
{
if
(
strlen
(
$piece
)
)
{
if
(
empty
(
$cursor
[
$piece
]
)
||
!
is_array
(
$cursor
[
$piece
]
)
)
{
$cursor
[
$piece
]
=
array
(
)
;
}
}
else
{
$cursor
[
]
=
array
(
)
;
$piece
=
last_key
(
$cursor
)
;
}
$cursor
=
&
$cursor
[
$piece
]
;
}
$cursor
=
$val
;
unset
(
$cursor
)
;
}
}
else
{
$input_arr
[
$key
]
=
$val
;
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Jan 19, 14:07 (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1113654
Default Alt Text
PhutilQueryStringParser.php (3 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment