2009-07-16 93 views
3

好的,所以我使用mod_rewrite和PHP編寫了一個REST API實現。我通過HTTP DELETE請求(... collective groan?)接受查詢字符串。除了前面兩種語句的智慧之外,我發現PHP不會自動分析DELETE請求的請求體(即儘管表單編碼的查詢字符串出現在請求體中,$ _POST仍然是空的)。這並沒有讓我感到特別意外。我發現令人驚訝的是,我一直無法找到一個用於解析查詢字符串的內置PHP函數?我只是忽略了一些東西?我可以這樣做:在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來處理這個問題。此外,我懷疑我不應該使用urldecode來清理表單編碼的值......它是一種不同的編碼,但我也無法辨別哪個PHP函數應該用於解碼錶單編碼的數據。

任何建議,將不勝感激。

回答

6

There's parse_str。不好的名字,但是做你想要的。並注意它沒有任何返回,第二個參數是通過引用傳遞的。

+0

'parse_str'不處理解析'$ _GET'酷似PHP做(不知道爲什麼)。看到我的答案爲我的「解決方案」。 – 2012-06-22 19:22:38

-1
public function parseQS($queryString, &$postArray){ 
    parse_str($queryString, $postArray); 
} 

;-)

+0

哈哈...顯然。 – codemonkey 2009-07-16 17:21:13

+0

有人對此投票?他顯然是在開玩笑......並不是真的建議我用我的功能包裝內置。 – codemonkey 2009-07-16 17:24:01

5

有是做它的功能 - http://php.net/parse_str。由於PHP必須自己做這件事,所以沒有理由不將它打開以便在API中使用。

將字符串到變量空隙 parse_str(字符串$ STR [,陣列& $ 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 
4

parse_strsucks

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()); 
} 
0

我已經構建了一個簡單的庫來解析查詢字符串來篩選,排序,並選擇我的休息API的字段。 odata的天真版本。 將查詢字符串轉換爲對象和/或對象數組。 用於離:

過濾器:

www.example.com/[email protected]=filedName operator 'the value' 

可用運算當量,NE,GT,LT,等,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 

easyparser