양식 제출시 PHP $ _POST 배열이 비어 있음


99

내 개발 상자 (Ubuntu / PHP5 + / MySQL5 +)에서 완벽하게 작동하는 사용자 지정 CMS가 있습니다.

방금 클라이언트의 프로덕션 상자로 옮겼고 이제 모든 양식 제출이 빈 $ _POST 배열로 표시됩니다.

데이터가 실제로 전달 file_get_contents('php://input');되고 있고 데이터가 잘 표시 되는지 확인하는 트릭을 찾았 습니다. $_POST/ $_REQUEST배열은 항상 비어 있습니다.

또한 방화범 ( application/x-www-form-urlencoded; charset=utf-8)을 통해 콘텐츠 유형 헤더가 올바른지 확인했습니다 .

이 문제는 양식이 AJAX를 통해 제출되는지 또는 일반 양식 제출인지에 관계없이 발생합니다.

어떤 도움이라도 대단히 감사합니다!

php  arrays  forms  post 

post_max_size 확인 : 값은 8MB가 아닌 8M으로 설정되어야합니다. 최신 경우에, 당신은 어떤 오류가 표시되지 않지만 $ _POST 크기는 0으로 설정됩니다
세르게이 카르 포프에게

답변:


186

이 질문은 양식을 통한 POST에 관한 것이지만 JSON 콘텐츠 유형으로 게시 할 때 유사한 문제에 대한 답변을 찾고 있습니다. 시간이 많이 걸리므로 답을 찾고 공유하고 싶었습니다.

JSON 콘텐츠 유형을 사용할 때 $ _POST 배열이 채워지지 않습니다 (내가 믿는 다중 파트 형식에서만).

문제를 해결하기 위해 작업 한 내용은 다음과 같습니다.

$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);

이것이 누군가를 돕기를 바랍니다!


이 해결 방법은 의미가 있습니다. 배치 업데이트 컨트롤러를 수정했습니다. :)
Martin Zeitler 2013-04-28

2
또 다른 대안은 Content-Type헤더를 로 변경 application/x-www-form-urlencoded한 다음 $.param(dataObject). 도움이 될 것입니다.
ŁukaszBachman 2015 년

1
@ ŁukaszBachman 데이터 객체가 ........ 같은 경우 그 작업을 수행하는 방법 title=something&body=anything. 제목과 본문의 가치를 얻고 싶습니다. $ dataobject [ "title"]은 비어 있음을 반환합니다. 제 경우에는 $ _POST가 비어 있습니다. 그리고 file_get_contents ( "php : // input") ...을 사용하여 얻을 수있는 유일한 방법은 json 인코딩이 아니라는 점입니다.
Khurshid Alam

이것은 매우 유용합니다. 이상한 점은 개발 시스템에서 Json을 보내는 데 문제가 없지만 프로덕션 시스템에 수행한다는 것입니다.
Simon H


86

또 다른 가능한 원인이 있습니다. 제 양식이 WWW없이 domain.com에 제출되었습니다. "WWW"를 추가하기 위해 자동 리디렉션을 설정했습니다. 프로세스에서 $ _POST 배열이 비워졌습니다. 이 문제를 해결하려면 www.domain.com에 제출하기 만하면되었습니다.


24
젠장, 내 URL 재 작성 htaccess이 POST가 작동하지 않는 원인이었습니다. 모든 URL에 자동으로 슬래시를 추가했지만 코드에서 ACTION으로 슬래시가없는 URL을 사용했습니다. .htaccess를 확인하지 않았기 때문에 귀하의 답변이 도움이되었습니다. +1
binar 2012 년

Godaddy를 사용하여 도메인 전달 (마스킹 포함)을했는데 이것이 문제의 원인 인 것 같습니다.
크리스 왕자

1
나는 또한 비슷한 문제가 있었는데 그것은 내 .htaccess파일 에서 나왔다 . .phpURL 에서 확장자를 제거 했고 내 양식은 확장자가있는 URL로 전송되었습니다 POST.
Emanuel Vintilă

25

비슷한 문제가있었습니다. 간단한 수정으로 판명되었습니다. 내가 가진 형태로

<form action = "directory"method = "post">

여기서 directory는 디렉토리의 이름입니다. 내 POST 어레이가 완전히 비어 있습니다. 내 브라우저에서 URL을 보았을 때 끝에 슬래시가 표시되었습니다.

내 작업 끝에 슬래시를 추가하면 트릭이 발생했습니다.

<form action = "directory /"method = "post">

내 $ _POST 어레이가 다시 가득 찼습니다!


1
예를 들어 이것은 좋은 라우팅 시스템을 가진 CakePHP에서 고쳐서는 안됩니다. 이것은 실패했습니다. 그러나 아파치에 대한 일부 구성,이 문제에 대해 추가 조사를하고 싶습니다. 꽤 흥미 롭습니다.
James

비슷한 메모에서 OP와 동일한 문제가 있었지만 <form>태그에 name속성 이없고 IE에서만 발생했습니다.
jkt123

13

php.ini에서 다음을 확인하십시오.

  • track_vars (아주 오래된 PHP 버전에서만 사용 가능) On
  • variables_order 편지를 포함 P
  • post_max_size 적절한 값 (예 : 8MB)으로 설정됩니다.
  • (수호신 패치를 사용하는 경우) suhosin.post.max_varssuhosin.request.max_vars대형 충분합니다.

내 두 번째 제안이 문제를 해결할 것이라고 생각합니다.


1
감사합니다 MrMage, 귀하의 통찰력에 감사 드리며 해당 ini 설정을 확인하고 그것이 트릭을했는지 알려줄 것입니다. 감사!

1
"post_max_size"설정이 제 최고입니다. 양식 제출 중에 큰 파일을 업로드했는데이 설정에는 값이 적습니다. 그래서 양식을 제출할 때 빈 포스트 배열이 생깁니다.
shasi kanth

9

HTTP에서 HTTPS로 게시 할 때 $_POST비어있는 것으로 나타났습니다 . 이것은 양식을 테스트하는 동안 발생했지만 그것을 깨닫기까지 시간이 걸렸습니다.


5

비슷하지만 약간 다른 문제를 발견했으며 문제를 이해하는 데 2 ​​일이 걸렸습니다.

  • 제 경우에도 POST 배열이 비어 있습니다.

  • 그런 다음 file_get_contents ( 'php : // input'); 그리고 그것도 비어있었습니다.

나중에 브라우저가 POST 제출 후로드 된 페이지를 새로 고치면 양식 데이터를 다시 제출할지 확인을 요청하지 않는 것을 발견했습니다. 직접 새로 고침 페이지였습니다. 그러나 양식 URL을 다른 URL로 변경하면 POST를 제대로 전달하고 페이지를 새로 고치려고 할 때 데이터를 다시 제출하도록 요청했습니다.

그런 다음 실제 URL에 무엇이 잘못되었는지 확인했습니다. URL에 결함이 없었지만 URL에 index.php가없는 폴더를 가리키고 있으며 index.php에서 POST를 확인했습니다.

여기에서 /에서 /index.php 로의 리디렉션으로 인해 POST 데이터가 손실되고 URL에 index.php를 추가하여 테스트 된 URL이 발생하는지 의심했습니다.

작동했습니다.

누군가가 도움이 될 수 있도록 여기에 게시했습니다.


1
URL 끝에 '/'가 없으면 $ _REQUEST에는 아무것도 없지만 '/'또는 '/index.php'를 사용하면 게시 된 모든 데이터가 $ _REQUEST에 존재합니다. 내 nginx 설정 또는 다른 것일 수 있습니다!
MohaMad 2017

4

이 시점에서 우아한 해결책은 없지만이 문제에 직면 한 다른 사람들의 향후 참조를 위해 내 결과를 공유하고 싶었습니다. 문제의 원인은 .htaccess 파일에있는 2 개의 재정의 된 php 값이었습니다. 파일 업로드에 대한 파일 크기 제한을 기본 8MB에서 더 큰 값으로 늘리기 위해이 두 값을 간단히 추가했습니다. 기본보다 크든 작든 htaccess 파일에이 두 값만 있으면 문제가 발생하는 것으로 나타났습니다. .

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

모든 suhosin.post.xxx/suhosin.upload.xxx vars에 대한 제한을 높이기 위해 추가 변수를 추가했지만 불행히도이 문제에 영향을 미치지 않았습니다.

요약하면 여기서 "이유"를 설명 할 수는 없지만 근본 원인을 확인했습니다. 내 느낌은 이것이 궁극적으로 suhosin / htaccess 문제이지만 불행히도 위의 2 PHP 재정의 값을 제거하는 것 외에는 해결할 수 없었던 문제입니다.

내가 이것을 알아내는 데 몇 시간을 죽였을 때 이것이 미래의 누군가에게 도움이되기를 바랍니다. 시간을내어 도와 주신 모든 분들께 감사드립니다 (MrMage, Andrew)


특히 문제가 서버 설정 / htaccess에있는 경우 Serverfault에서이 질문을 할 가치가 있습니다.
다윗은 분석 재개 모니카 말한다

5
내가 착각하지 않았다면, 크기는 'xxMB'가 아닌 'xxM'과 같이 지정되어야합니다. 그래서 그것과 관련이 있을지 궁금합니다 ...
JC Inacio

4

기본값은 "text / plain"이므로 enctype = "application / x-www-form-urlencoded"를 사용하여 문제를 해결할 수 있습니다. $ DATA를 체크인 할 때 구분자는 "text / plain"을위한 공백과 "urlencoded"를위한 특수 문자입니다.

친절한 안부 프랭크


4

갖는 enable_post_data_reading설정을 비활성화하면이 발생합니다. 문서에 따르면 :

enable_post_data_reading

이 옵션을 비활성화하면 $ _POST 및 $ _FILES가 채워지지 않습니다. postdata를 읽는 유일한 방법은 php : // input 스트림 래퍼를 통하는 것입니다. 이는 요청을 프록시하거나 메모리 효율적인 방식으로 POST 데이터를 처리하는 데 유용 할 수 있습니다.


4

예를 들어 /api/index.php와 같은 디렉토리의 index.php 파일에 게시하는 경우 양식에서 파일에 대한 전체 디렉토리를 지정했는지 확인하십시오.

<form method="post" action="/api/index.php"> 
</form>

또는

<form method="post" action="/api/"> 
</form>

공장.

그러나 이것은 실패합니다

<form method="post" action="/api"> 
</form>

사실 정반대입니다. 나는 그것이 /my_uri작동하지만 그렇지 않다는 것을 발견했습니다 /my_uri/.
Link14

같은 문제가있었습니다. apache 또는 nginx가 / api에서 / api /로 리디렉션을 추가하는 것 같습니다.
John Smith

4
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

좋아, 이것은 어리석은 일이었고 공개적으로 내 자신을 당황하게 할 것이지만 PHP에서 무언가에 대한 약간의 테스트 스크립트를 두 드렸고 내 $_POST배열이 비어 있을 때 StackOverflow가 내가 처음 보았고 필요한 답을 찾지 못했습니다. .

나는 단지 썼다

<form action="test.php">

방법을 POST! 로 지정하는 것을 잊었습니다 .

나는 누군가가 찡그린다고 확신하지만, 이것이 같은 일을하는 다른 사람에게 도움이된다면, 나는 상관하지 않는다! 우리 모두는 때때로 그것을합니다!


믿을 수 없어 나도 잊었 어! 나는 단지 새로운 서버를 시도하고 있는데, 그것은 구성으로 인한 일이었습니다 ... 어쨌든, 상기시켜 주셔서 감사합니다!
Samuel Aiala Ferreira

4

제 경우에는 HTTP에서 HTTPS로 게시 할 때 $ _POST가 비어 있습니다. 문제는 양식에 //example.com과 같은 동작이 있다는 것입니다. URL을 https://example.com으로 수정 하면 문제가 사라졌습니다.


1
나는 서버가 설정되는 방법과 관련된 것이라고 생각합니다. GoDaddy를 호스트로 사용하는 것과 동일한 문제가 있습니다. 이 솔루션은 문제를 해결하지 못했습니다.
acarlstein

이 솔루션은 내 문제를 해결했습니다. 나는 좋은 머리를 가졌다.
gokaysatir

3

여기에 같은 문제!

우편 배달부에서 우편 요청을 통해 로컬 서버 코드에 연결하려고했는데이 문제로 인해 많은 시간이 낭비되었습니다!

로컬 프로젝트 (예 : 우편 배달부)를 사용하는 모든 사람 : "localhost"키워드 대신 IPv4 주소 (cmd에 ipconfig 입력)를 사용합니다. 나의 경우에는:

전에:

localhost/app/login

후:

192.168.1.101/app/login

Postman은 인용 부호 또는 공백이있는 긁힌 json 값에 대한 몇 가지 문제를 제공했습니다. 특정 형식이 필요합니다.
Tom Anderson 19

2

참조 : http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

POST 방법

요청을 보낼 때 POST 메서드가 사용되도록 몇 가지 수정을 할 것입니다.

var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);

//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}
http.send(params);

일부 http 헤더는 POST 요청과 함께 설정되어야합니다. 그래서 우리는 그것들을이 줄에 설정했습니다 ...

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

위의 줄에서 우리는 기본적으로 데이터 전송이 양식 제출 형식이라고 말합니다. 또한 우리가 보내는 매개 변수의 길이를 제공합니다.

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}

'준비 상태'변경 이벤트에 대한 핸들러를 설정합니다. 이것은 GET 메서드에 사용한 것과 동일한 핸들러입니다. 여기에서 http.responseText를 사용할 수 있습니다-innerHTML (AHAH), eval it (JSON) 또는 다른 것을 사용하여 div에 삽입하십시오.

http.send(params);

마지막으로 요청과 함께 매개 변수를 보냅니다. 주어진 URL은이 줄이 호출 된 후에 만로드됩니다. GET 메소드에서 매개 변수는 널값이됩니다. 그러나 POST 메소드에서는 전송할 데이터가 send 함수의 인수로 전송됩니다. params 변수는 두 번째 줄에서 다음과 같이 선언되었습니다. lorem=ipsum&name=binny따라서 두 개의 매개 변수 인 'lorem'과 'name'을 각각 'ipsum'과 'binny'값으로 보냅니다.


1

제 경우에는 jQuery를 사용하여 양식을 제출하기 직전에 jQuery를 사용하여 페이지의 모든 입력을 비활성화했기 때문입니다. 그래서 "숨겨진"유형도 "모든 입력을 비활성화"로 변경했습니다.

$(":input").attr("disabled","disabled"); 

" '버튼'유형 입력 만 비활성화":

$('input[type=button]').attr('disabled',true);

이것은 사용자가 실수로 '이동'버튼을 두 번 누르고 DB를 꽉 채우지 않도록하기위한 것입니다! '숨겨진'유형의 양식에 'disabled'속성을 입력하면 양식이 제출되면 값이 전송되지 않는 것 같습니다!


1

나를 위해, .htaccess는 mod_rewrite가 설치되지 않았을 때 리디렉션되었습니다. mod_rewite를 설치하면 모두 괜찮습니다.

구체적으로 특별히:

<IfModule !mod_rewrite.c>
  ErrorDocument 404 /index.php
</Ifmodule>

실행 중이었습니다.


1

비슷한 문제를 해결하기 위해 몇 시간을 보냈습니다. 제 경우의 문제는

max_input_vars = "1000"

기본적으로 php.ini에 있습니다. 나는 업로드없이 정말 거대한 형태를 가졌다. php.ini는 upload_max_filesize = "100M"및 post_max_size = "108M"로 설정되어 있으며 제 경우에는 확실히 문제가되지 않았습니다. PHP 동작은 max_input_vars 양식에서 변수가 1000 개를 초과 할 때 동일합니다. 반환하고 _POST 배열을 비 웁니다. 나는 그것을 한 시간, 그리고 몇 시간 전에 발견 할 수 있었으면했다.


1

나는 이것이 오래되었다는 것을 알고 있지만 내 솔루션을 공유하고 싶었습니다.

제 경우에는 PHP의 최대 업로드 제한을 높이기 위해 변수를 추가함에 따라 .htaccess에 문제가있었습니다. 내 코드는 다음과 같습니다.

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

나중에 값이 xxMB가 아닌 xxM과 같아야하며 다음과 같이 변경했을 때 알 수 있습니다.

php_value post_max_size 50M
php_value upload_max_filesize 50M

이제 내 $ _POST가 이전에 정상적으로 데이터를 반환했습니다. 이것이 미래의 누군가에게 도움이되기를 바랍니다.


0

MRMage의 게시물 외에도 :

일부 $_POST변수 (큰 배열> 1000 개 항목 포함)가 사라지는 문제를 해결하기 위해이 변수를 설정해야했습니다 .

suhosin.request.max_vars = 2500

" request"이 아니라 " post"이 (가) 해결책이었습니다 ...


0

아마도 가장 편리한 솔루션은 아니지만 양식 action속성을 루트 도메인으로 설정하면 index.php에 액세스 할 수 있고 게시 된 변수를 가져올 수 있다는 것을 알았 습니다. 그러나 다시 작성된 URL을 작업으로 설정하면 작동하지 않습니다.


0

이것은 @icesar가 말한 것과 유사합니다 .

그러나 나는에있는 내 api에 물건을 게시하려고했지만 자체적으로 전달되기 때문에에 site/api/index.php게시 site/api했습니다 index.php. 그러나 이것은 내가 $_POST즉석에서 비워 졌기 때문에 분명히 뭔가 엉망이되는 원인이됩니다 . site/api/index.php대신 직접 게시하면 해결되었습니다.


0

내 문제는 HTML <base>태그를 사용하여 테스트 사이트의 기본 URL을 변경하는 것입니다. 헤더에서 해당 태그를 제거하면 $_POST데이터가 다시 나타납니다.


0

제 경우에는 (OVH 상호 서버의 PHP 페이지) enctype="text/plain"가 작동하지 않으며 ( $_POST해당 항목 $_REQUEST이 비어 있음) 아래의 다른 예제가 작동합니다. `

<form action="?" method="post">
<!-- in this case, my google chrome 45.0.2454.101 uses -->
<!--     Content-Type:application/x-www-form-urlencoded -->
    <input name="say" value="Hi">
    <button>Send my greetings</button>
</form>

<form action="?" method="post" enctype="application/x-www-form-urlencoded">
    <input name="say" value="Hi">
    <button>Send my application/x-www-form-urlencoded greetings</button>
</form>

<form action="?" method="post"  enctype="multipart/form-data">
    <input name="say" value="Hi">
    <button>Send my multipart/form-data greetings</button>
</form>

<form action="?" method="post" enctype="text/plain"><!-- not working -->
    <input name="say" value="Hi">
    <button>Send my text/plain greetings</button>
</form>

`

여기 더 : method = "post"enctype = "text / plain"이 호환되지 않습니까?


0

Mod Security에서 다음 오류가 발생했습니다.

Access denied with code 500 (phase 2). Pattern match "((select|grant|delete|insert|drop|alter|replace|truncate|update|create|rename|describe)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]+[[:space:]]+(from|into|table|database|index|view)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]|UNION SELECT.*\'.*\'.*,[0-9].*INTO.*FROM)" at REQUEST_BODY. [file "/usr/local/apache/conf/modsec2.user.conf"] [line "345"] [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]

테스트를 위해 모드 보안 구성을 제거하면 모두 예상대로 작동했습니다. 이제 규칙을 수정하여 보안을 유지하면서도 필요에 따라 충분히 유연하게해야합니다. :)


0

입력 태그에 name = " your_variable_name " 을 사용해야 합니다.

실수로 id = " your_variable_name "을 사용했습니다.

버그를 잡기 위해 많은 시간을 보냈습니다.


0

name각 필드 의 속성이 정의되어 있는지 확인하십시오 .

이것은 PHP에서 빈 POST를 생성합니다.

<input type="text" id="Phone">

그러나 이것은 작동합니다

<input type="text" name="Phone" id="Phone">

나는 서버가 설정되는 방법과 관련된 것이라고 생각합니다. GoDaddy를 호스트로 사용하는 것과 동일한 문제가 있습니다. 이 솔루션은 문제를 해결하지 못했습니다.
acarlstein

-1

좋아요, 제 케이스를 여기에 넣어야한다고 생각했습니다 .... 특정한 경우에 포스트 배열을 비워 두었습니다 .. 양식은 잘 작동하지만 사용자가 제출 버튼을 눌렀다 고 불평하고 아무 일도 일어나지 않습니다 .... 잠시 파헤친 후, 호스팅 회사가 사용자 입력을 확인하고 발견되면 전체 게시물 배열 (악성 데이터뿐만 아니라)을 지우는 보안 모듈이 있음을 발견했습니다. 제 예에서 한 수학 교사가 방정식을 입력하려고했습니다. dy + dx + 0 = 0; 데이터가 완전히 삭제되었습니다.

이 문제를 해결하려면 텍스트 영역에 dy + dx + 0 = 0으로 데이터를 입력하라고 조언합니다. 이제 작동합니다. .... 이렇게하면 누군가 시간을 절약 할 수 있습니다 ..


5
사용자에게 잘못된 코드에 대한 허용을 요청하는 것은 시작이 아닙니다.
freeworlder 18.11.02

실제로 잘못된 코드는 아니지만 새로운 호스팅 공급자를 고려할 수 있습니다. 또는 HTML URL 인코딩과 같은 다른 형식으로 입력을 게시합니다.
Tom Anderson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.