4

好的,所以我已经使用 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 和 urldecode 来清理表单编码的值......这是一种不同的编码,但我也无法辨别我应该使用哪个 PHP 函数来解码表单编码的数据.

任何建议将不胜感激。

4

7 回答 7

8

parse_str。名字不好,但做你想做的事。注意它什么都不返回,第二个参数是通过引用传递的。

于 2009-07-16T17:18:22.500 回答
6

有一个功能可以做到 - http://php.net/parse_str。由于 PHP 必须为自己执行此操作,因此没有理由不将其开放用于 API。

将字符串解析为变量 void parse_str ( string $str [, array &$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
于 2009-07-16T17:21:17.267 回答
4

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() );
}
于 2012-06-14T23:57:24.467 回答
2

http://us2.php.net/manual/en/function.parse-url.php

parse_url 将帮助您获取包含实际查询的 DOCUMENT_URI 部分。

然后,您可以将该部分传递给 parse_str 以从查询中提取单个元素。

http://us2.php.net/manual/en/function.parse-str.php

于 2009-07-16T17:32:01.910 回答
2

您可以使用以下parse_str功能

parse_str($queryString, $args);
于 2009-07-16T17:18:32.360 回答
0

我已经构建了一个简单的库来解析查询字符串以过滤、排序和选择我的 rest 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

嵌入:

@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

易解析器

于 2016-09-19T22:16:34.530 回答
-1
public function parseQS($queryString, &$postArray){
  parse_str($queryString, $postArray);
}

;-)

于 2009-07-16T17:20:18.173 回答