PHP의 쿼리 문자열 디코딩
-
16-09-2019 - |
문제
자, 그래서 나는 mod_rewrite와 php를 사용하여 REST API 구현을 작성했습니다. HTTP 삭제 요청 본문을 통해 쿼리 문자열을 수락하고 있습니다 (... Collective Groan?). 두 가지 이전 진술의 지혜에 대한 논쟁을 제외하고, 내가 찾은 것은 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 내장이 없을 것이라는 것은 이상하게 보입니다. 또한 폼 인코딩 된 값을 문지르기 위해 htmlspecialcharacters & urldecode를 사용해서는 안된다고 생각합니다 ... 다른 종류의 인코딩이지만, 양식 인코딩 데이터를 해독하는 데 사용해야 할 PHP 기능을 분별하는 데 어려움이 있습니다. .
모든 제안에 감사드립니다.
해결책
거기 있습니다 parse_str. 나쁜 이름이지만 원하는대로합니다. 그리고 그것이 아무것도 반환하지 않으며, 두 번째 인수는 참조로 전달됩니다.
다른 팁
그것을하는 함수가 있습니다. http://php.net/parse_str. PHP는 자체적 으로이 작업을 수행해야하므로 API에서 사용하기 위해 열리지 않을 이유가 없습니다.
문자열을 변수로 구문 분석하여 parse_str (String $ str [, array & $ arr])
마치 URL을 통해 전달되는 쿼리 문자열 인 것처럼 str을 구문 분석하고 현재 범위에서 변수를 설정합니다.
<?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
parse_str
짜증나.
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() );
}
당신은 사용할 수 있습니다 parse_str
기능:
parse_str($queryString, $args);
http://us2.php.net/manual/en/function.parse-url.php
parse_url은 실제 쿼리가 포함 된 Document_uri의 일부를 잡는 데 도움이됩니다.
그런 다음 해당 섹션을 Parse_str로 전달하여 쿼리에서 개별 요소를 추출 할 수 있습니다.
쿼리 문자열을 구문 분석하여 REST API의 필드를 필터링하고 정렬하고 선택할 수있는 간단한 라이브러리를 만들었습니다. 순진한 버전의 Odata. 쿼리 문자열은 개체 및 또는 객체의 배열로 변환되었습니다. 예 :
필터 :
www.example.com/resource?@filters=filedName operator 'the value'
사용 가능한 운영자 EQ, NE, GT, LT, Like, 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
public function parseQS($queryString, &$postArray){
parse_str($queryString, $postArray);
}
;-)