PHP가 $_GET 또는 $_POST 배열에서 ‘.’ 문자의 치환을 중지하도록 합니다.

PHP 변수를 전달하면.$_GET PHP를 통한 사용자 이름으로 자동 대체_성격.예를 들어 다음과 같습니다.

<?php echo "url is ".$_SERVER['REQUEST_URI']."<p>"; echo "x.y is ".$_GET['x.y'].".<p>"; echo "x_y is ".$_GET['x_y'].".<p>"; 

…는 다음을 출력합니다.

url is /SpShipTool/php/testGetUrl.php?x.y=a.b x.y is . x_y is a.b. 

…내 질문은 이것이다: 내가 이 일을 멈출 수 있는 방법은 없을까?내가 뭘 했기에 이런 일을 당했는지 아무리 생각해도 모르겠어

현재 사용하고 있는 PHP 버전은 5.2.4-2ubuntu5.3입니다.



질문에 대한 답변



그 이유에 대한 PHP.net의 설명은 다음과 같습니다.

들어오는 변수 이름의 점

일반적으로 PHP는 스크립트로 전달될 때 변수 이름을 변경하지 않습니다.단, 점( 마침표, 마침표)은 PHP 변수 이름의 유효한 문자가 아닙니다.그 이유는 다음과 같습니다.

<?php $varname.ext;
/* invalid variable name */ ?> 

여기서 파서에는 $varname이라는 변수 뒤에 문자열 연결 연산자가 이어지며 barestring(알려진 키 또는 예약된 단어와 일치하지 않는 따옴표로 묶이지 않은 문자열) ‘ext’가 나타납니다.분명히, 이것은 의도한 결과가 아닙니다.

따라서 PHP는 들어오는 변수 이름에 있는 모든 점을 자동으로 밑줄로 바꿉니다.

http://ca.php.net/variables.external에서 보내드립니다.

또, 코멘트에 의해, 다음의 다른 문자는 밑줄로 변환됩니다.

PHP가 _(밑줄)로 변환하는 필드 이름 문자의 전체 목록은 다음과 같습니다(점뿐 아니라).

  • chr(32) ( ) (스페이스)
  • chr(46) (.) (점)
  • chr(91) ([])(열린 대괄호)
  • chr(128) – chr(159)(표준)

이 경우 dawnerd의 제안을 사용하여 밑줄을 점으로 변환해야 합니다(단, str_replace를 사용합니다).




오랫동안 질문에 답했지만 실제로는 더 나은 답변(또는 회피책)이 있습니다.PHP를 사용하면 원시 입력 스트림에서 다음과 같은 작업을 수행할 수 있습니다.

$query_string = file_get_contents('php://input'); 

그러면 $_POST 배열이 쿼리 문자열 형식으로 표시됩니다. 마침표는 필수입니다.

그런 다음 필요에 따라 해석할 수 있습니다(POSTer의 코멘트에 따라 주세요.

<?php // Function to fix up PHP's messing up input containing dots, etc. // `$source` can be either 'POST' or 'GET' function getRealInput($source) {
$pairs = explode("&", $source == 'POST' ? file_get_contents("php://input") : $_SERVER['QUERY_STRING']);
$vars = array();
foreach ($pairs as $pair) {
$nv = explode("=", $pair);
$name = urldecode($nv[0]);
$value = urldecode($nv[1]);
$vars[$name] = $value;
}
return $vars; }
// Wrapper functions specifically for GET and POST: function getRealGET() { return getRealInput('GET'); } function getRealPOST() { return getRealInput('POST'); } ?> 

오픈에 큰 도움이 되다ID 매개 변수. 각각 ‘.’와 ‘_’를 모두 포함하며, 각각 특정 의미를 가집니다.




위의 코멘트에서 Johan에 의한 실제 답변을 강조 표시 – 저는 방금 투고 전체를 문제를 완전히 우회하는 톱 레벨 어레이로 정리했습니다.부하 처리는 필요 없습니다.

당신이 하는 형태로

<input name="data[database.username]">
<input name="data[database.password]">
<input name="data[something.else.really.deep]">

대신

<input name="database.username">
<input name="database.password">
<input name="something.else.really.deep">

포스트 핸들러에서 개봉하기만 하면 됩니다.

$posdata = $_POST['data']; 

나의 견해는 완전히 틀에 박힌 것이었기 때문에, 나에게 이것은 두 줄의 변화였다.

참고로, 필드 이름에 점을 사용하여 그룹화된 데이터의 트리를 편집합니다.




표준규격에 준거하여 딥 어레이와 연동되는 솔루션을 원하십니까(예:?param[2][5]=10) ?

이 문제의 가능한 모든 원인을 수정하려면 PHP 코드 맨 위에 신청하십시오.

$_GET
= fix( $_SERVER['QUERY_STRING'] ); $_POST
= fix( file_get_contents('php://input') ); $_COOKIE = fix( $_SERVER['HTTP_COOKIE'] ); 

이 기능은 2013년 여름휴가 때 생각해 낸 멋진 아이디어입니다.단순한 regex에 실망하지 마십시오. 모든 쿼리 이름을 가져와 인코딩한 다음(그래서 점이 보존됨) 일반을 사용합니다.parse_str()기능.

function fix($source) {
$source = preg_replace_callback(
'/(^ (?<=&))[^=[&]+/',
function($key) { return bin2hex(urldecode($key[0])); },
$source
);
parse_str($source, $post);
$result = array();
foreach ($post as $key => $val) {
$result[hex2bin($key)] = $val;
}
return $result; } 



이는 마침표가 변수 이름에 유효하지 않은 문자이기 때문에 발생하며, 이유는 PHP 구현에 매우 깊이 있기 때문에 쉬운 수정은 아직 없습니다.

그 사이에, 다음의 방법으로 이 문제를 해결할 수 있습니다.

  1. 다음 중 하나를 통해 원시 쿼리 데이터 액세스php://inputPOST 데이터의 경우 또는$_SERVER['QUERY_STRING']GET 데이터용
  2. 변환 함수를 사용합니다.

아래 변환 함수(PHP > = 5.4)는 각 키-값 쌍의 이름을 16진수 표현으로 인코딩한 후 정기적으로 수행합니다.parse_str();가 완료되면 16진수 이름을 원래 형식으로 되돌립니다.

function parse_qs($data) {
$data = preg_replace_callback('/(?:^ (?<=&))[^=[]+/', function($match) {
return bin2hex(urldecode($match[0]));
}, $data);
parse_str($data, $values);
return array_combine(array_map('hex2bin', array_keys($values)), $values); }
// work with the raw query string $data = parse_qs($_SERVER['QUERY_STRING']); 

또는 다음 중 하나를 선택합니다.

// handle posted data (this only works with application/x-www-form-urlencoded) $data = parse_qs(file_get_contents('php://input'));