好的,所以我使用mod_rewrite和PHP编写了一个REST API实现。我通过HTTP DELETE请求(...集体呻吟?)接受一个查询字符串。关于前面两个语句的智慧的争论不谈,我发现PHP不会自动解析DELETE请求的请求体(即,尽管在请求体中出现了表单编码的查询字符串,$ _POST仍为空)。这并不特别让我感到惊讶。我发现令人惊讶的是,我一直无法找到用于解析查询字符串的内置PHP函数?我只是忽略了什么?我可以这样做:
public function parseQS($queryString, &$postArray){
$queryArray = explode('&', $queryString);
for($i = 0; $i < count($queryArray); $i++) {
$thisElement = split('=', $queryArray[$i]);
$postArray[$thisElement[0]] = htmlspecialchars(urldecode($thisElement[1]));
}
}
...看起来很奇怪,没有PHP内置来处理这个问题。另外,我怀疑我不应该使用htmlspecialcharacters&amp; urldecode用于擦除表单编码的值...这是一种不同的编码方式,但我也无法识别我应该使用哪种PHP函数来解码表单编码数据。
任何建议都将受到赞赏。
答案 0 :(得分:8)
有parse_str。不好的名字,但做你想要的。并注意它没有返回任何内容,第二个参数通过引用传递。
答案 1 :(得分:5)
有一个功能 - http://php.net/parse_str。由于PHP必须为自己执行此操作,因此没有理由不打开它以在API中使用。
将字符串解析为变量void parse_str(string $ str [,array&amp; $ arr])
解析str就好像是查询一样 字符串通过URL传递并设置 当前范围内的变量。
<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str, $output);
echo $output['first']; // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz
答案 2 :(得分:4)
parse_str
sucks。 parse_str
对于简单的东西很好,但它与PHP建立$_GET
魔术变量的构建方式不同。为什么?!?我不知道。我已经开发了我自己的版本,我认为它完全匹配PHP的解析(如果你能找到任何显示其他的例子,请告诉我。)
function betterParseStr( $string )
{
return array_reduce( explode( "&", $string ), function( $array, $string_piece ) {
if( $string_piece === "" ) return $array;
$equal_offset = strpos( $string_piece, "=" );
if( $equal_offset === FALSE ) {
$key = urldecode( $string_piece );
$value = "";
} else {
$key = urldecode( substr( $string_piece, 0, $equal_offset ) );
$value = urldecode( substr( $string_piece, $equal_offset + 1 ) );
}
if( preg_match( "/^([^\[]*)\[([^\]]*)](.*)$/", $key, $matches ) ) {
$key_path = array( $matches[1], $matches[2] );
$rest = $matches[3];
while( preg_match( "/^\[([^\]]*)](.*)$/", $rest, $matches ) ) {
$key_path[] = $matches[1];
$rest = $matches[2];
}
} else {
//replace first [ for _
//why?!? idk ask PHP it does
//Example: ?key[[=value -> array( "key_[" => "value" )
$key_path = array( preg_replace('/\[/', '_', $key, 1 ) );
}
if( strlen( $key_path[0] ) > 0 && substr( $key_path[0], 0, 1 ) !== "[" ) {
$current_node = &$array;
$last_key = array_pop( $key_path );
$resolve_key = function( $key, array $array ) {
if( $key === "" || $key === " " ) {
$int_array = array_filter( array_keys( $array ), function( $key ) { return is_int( $key ); } );
$key = $int_array ? max( $int_array ) + 1 : 0;
}
return $key;
};
foreach( $key_path as $key_path_piece ) {
$key_path_piece = $resolve_key( $key_path_piece, $current_node );
if( ! array_key_exists( $key_path_piece, $current_node ) || ! is_array( $current_node[$key_path_piece] ) ) {
$current_node[$key_path_piece] = array();
}
$current_node = &$current_node[$key_path_piece];
}
$current_node[$resolve_key( $last_key, $current_node )] = $value;
}
return $array;
}, array() );
}
答案 3 :(得分:2)
您可以使用parse_str
function:
parse_str($queryString, $args);
答案 4 :(得分:2)
http://us2.php.net/manual/en/function.parse-url.php
parse_url将帮助您获取包含实际查询的DOCUMENT_URI部分。
然后,您可以将该部分传递给parse_str,以从查询中提取单个元素。
答案 5 :(得分:0)
我已经构建了一个简单的库来解析查询字符串,以便为我的其余api过滤,排序和选择字段。一个天真的odata版本。 查询字符串转换为对象和/或对象数组。 例如:
过滤器:
www.example.com/resource?@filters=filedName operator 'the value'
可用运营商eq,ne,gt,lt,like,ilike,le,ge
$filtersResult = $parser->filters();
$filtersResult[0]->field // name
$filtersResult[0]->operator // eq
$filtersResult[0]->getOperator() // "="
$filtersResult[0]->value // 'what ever'
排序:
//name is asc , surname desc
@orderby=name,-surname
$sorts = $parser->orderBy() // you can set defaults if u want
$sorts[0]->filed //name
$sorts[0]->direction //asc
$sorts[1]->filed //surname
$sorts[1]->direction //desc
for embed:
@embed=resourceOne(@fields=name,code)(@filters=nameembed eq 'what ever'),mobiles(@orderby=sortFieldOne)
$embedResult = $parser->embed(); //return array of embed each
//object contains filters , sort , fields | empty array
$embedResult[0]->resource // resourceOne
$embedResult[0]->fields // array of fields [name,code]
$embedResult[0]->filters // array of filters or empty array
$embedResult[1]->resource // mobiles
$embedResult[1]->orderBy // array of order by objects
答案 6 :(得分:-1)
public function parseQS($queryString, &$postArray){
parse_str($queryString, $postArray);
}
- )