array php $ _POST vazio no envio do formulário

99

Eu tenho um CMS personalizado que construí que funciona perfeitamente na minha dev box (Ubuntu / PHP5 + / MySQL5 +).

Acabei de movê-lo para a caixa de produção do meu cliente e agora todos os envios de formulários estão aparecendo como arrays $ _POST vazios.

Eu descobri um truque para verificar se os dados estão realmente sendo passados ​​usando file_get_contents('php://input');e os dados estão aparecendo bem ali - os $_POST/ $_REQUESTarrays estão sempre vazios.

Eu também verifiquei que os cabeçalhos de tipo de conteúdo estão corretos via firebug ( application/x-www-form-urlencoded; charset=utf-8).

Esse problema está acontecendo independentemente de um formulário ser enviado via AJAX ou um envio de formulário normal.

Qualquer ajuda é muito apreciada!


fonte
Verifique post_max_size: o valor deve ser definido como 8M, não 8 MB. No último caso, você não verá nenhum erro, mas o tamanho de $ _POST será definido como 0
Sergei Karpov

Respostas:

186

Eu sei que esta pergunta era sobre o POST por meio de um formulário, mas vim aqui em busca de respostas para problemas semelhantes ao fazer o POST com o tipo de conteúdo JSON. Encontrei a resposta e queria compartilhá-la, pois me custou muito tempo.

Ao usar o tipo de conteúdo JSON, a matriz $ _POST não será preenchida (acredito que apenas com formulários de várias partes)

Aqui está o que funcionou para corrigir o problema:

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

espero que isso ajude alguém!

inclinar
fonte
Esta solução alternativa faz sentido - ela corrigiu meu controlador de atualização em lote :)
Martin Zeitler
2
Outra alternativa é alterar o Content-Typecabeçalho para application/x-www-form-urlencodede serializar seus dados com $.param(dataObject). Isso deve ajudar.
ŁukaszBachman
1
@ ŁukaszBachman Como fazer isso se dataobject é algo como ........ title=something&body=anything. Eu quero obter o vale de título e corpo. $ dataobject ["title"] retorna vazio. No meu caso, $ _POST está vazio. E a única maneira de obtê-lo usando file_get_contents ("php: // input") ... exceto que não é codificado em json.
Khurshid Alam
Isso é muito útil. O estranho é que não tenho problemas em enviar Json na minha máquina de desenvolvimento, mas sim na de produção.
Simon H
86

Aqui está outra causa possível - meu formulário foi enviado para domain.com sem a WWW. e configurei um redirecionamento automático para adicionar o "WWW". O array $ _POST estava sendo esvaziado no processo. Então, para consertar tudo que eu tive que fazer foi enviar para www.domain.com


fonte
24
Droga, uma reescrita de url no meu htaccessfoi a causa dos POSTs não funcionarem. Eu estava acrescentando barra automaticamente a todos os urls, mas no código como a AÇÃO estava usando um url sem barra. Sua resposta ajudou, pois nunca pensei em verificar o .htaccess. +1
binar
Tive o encaminhamento de domínio (com mascaramento) usando o Godaddy, e essa parece ser a origem do problema. Obrigado!
Chris Prince
1
Eu também tive um problema semelhante, estava vindo do meu .htaccessarquivo. Ele estava removendo a .phpextensão do URL e meu formulário estava POSTindo para o URL com a extensão.
Emanuel Vintilă
25

Eu tive um problema parecido. Acabou sendo uma solução simples. Na forma que eu tinha

<form action = "diretório" method = "post">

onde diretório era o nome de ... o diretório. Minha matriz POST estava totalmente vazia. Quando olhei para o url em meu navegador, ele foi exibido com uma barra no final.

Adicionar a barra ao final da minha ação resolveu -

<form action = "diretório /" method = "post">

Meu array $ _POST estava cheio novamente!

Randy Kilwag
fonte
1
Isso não deveria ser uma correção, por exemplo no CakePHP, que tem um bom sistema de roteamento, falhou nisso (não quero dizer que o Cake falhou), talvez a abordagem para este problema não seja o framework ou os arquivos .php, mas algumas configurações no apache, gostaria de fazer uma investigação mais aprofundada sobre este problema. É bem interessante.
James
Em uma nota semelhante, eu tive o mesmo problema que o OP, mas apenas se a <form>tag não tivesse um nameatributo, e apenas no IE.
jkt123
13

Certifique-se de que, em php.ini:

  • track_vars (está disponível apenas em versões de PHP muito antigas) está definido como On
  • variables_order contém a carta P
  • post_max_size está definido para um valor razoável (por exemplo, 8 MB)
  • (se estiver usando adesivo suhosin) suhosin.post.max_varse suhosin.request.max_varssão grandes o suficiente.

Suponho que a segunda sugestão minha resolverá seu problema.

MrMage
fonte
1
Obrigado MrMage, agradeço sua visão e irá verificar as configurações ini e informá-lo se isso funcionou. Obrigado!
1
A configuração "post_max_size" é o meu obstáculo. Eu estava carregando um arquivo grande durante o envio do formulário e esta configuração continha um valor menor. Portanto, estou recebendo uma matriz de postagem vazia ao enviar o formulário.
shasi kanth
9

Descobri que, ao postar de HTTP para HTTPS, o $_POSTvem vazio. Isso aconteceu durante o teste do formulário, mas demorei um pouco até perceber isso.

Marcos
fonte
5

Eu me deparei com um problema semelhante, mas ligeiramente diferente, e demorei 2 dias para entender o problema.

  • No meu caso, também o array POST estava vazio.

  • Em seguida, verificado com file_get_contents ('php: // input'); e também estava vazio.

Mais tarde, descobri que o navegador não estava pedindo confirmação para reenviar os dados do formulário após Se eu atualizar a página carregada após o envio do POST. Foi uma página diretamente refrescante. Mas quando mudei o URL do formulário para um diferente, ele estava passando o POST corretamente e pedia para reenviar os dados ao tentar atualizar a página.

Então eu verifiquei o que há de errado com o URL real. Não houve falha com URL, no entanto, ele estava apontando para uma pasta sem index.php na URL e eu estava verificando o POST em index.php.

Aqui eu duvido que o redirecionamento de / para /index.php faça com que os dados do POST sejam perdidos e o URL testado com index.php anexado ao URL.

Isso funcionou.

Poste aqui para que alguém ache útil.

GUIR
fonte
1
Tive o mesmo problema, sem '/' no final da url, não existe nada em $ _REQUEST, mas com '/' ou '/index.php', todos os dados postados existem em $ _REQUEST. Pode ser minhas configurações nginx ou outra coisa!
MohaMad
4

Não tenho uma solução elegante neste momento, mas gostaria de compartilhar minhas descobertas para referência futura de outras pessoas que encontrarem esse problema. A origem do problema eram 2 valores de php substituídos em um arquivo .htaccess. Eu simplesmente adicionei esses 2 valores para aumentar o limite de tamanho de arquivo para uploads de arquivo dos 8 MB padrão para algo maior - observei que simplesmente ter esses 2 valores no arquivo htaccess, seja maior ou menor do que o padrão, causava o problema .

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

Eu adicionei variáveis ​​adicionais para aumentar os limites de todas as vars suhosin.post.xxx/suhosin.upload.xxx, mas infelizmente elas não tiveram nenhum efeito com esse problema.

Em resumo, não consigo explicar o "porquê" aqui, mas identifiquei a causa raiz. Meu sentimento é que este é, em última análise, um problema de suhosin / htaccess, mas infelizmente um que eu não fui capaz de resolver além de remover os 2 valores substituídos de php acima.

Espero que isso ajude alguém no futuro, já que matei um punhado de horas tentando descobrir isso. Obrigado a todos que despenderam tempo para me ajudar com isso (MrMage, Andrew)


fonte
Pode valer a pena fazer essa pergunta no Serverfault, principalmente se o problema estiver na configuração do servidor / htaccess.
David diz para restabelecer Monica de
5
Se não me engano, o tamanho deve ser especificado como 'xxM', e não 'xxMB', então eu me pergunto se isso pode ter algo a ver com isso ...
JC Inácio
4

Eu poderia resolver o problema usando enctype = "application / x-www-form-urlencoded" já que o padrão é "text / plain". Quando você faz check-in de $ DATA, o separador é um espaço para "text / plain" e um caractere especial para "urlencoded".

Atenciosamente Frank

RudeUrm
fonte
4

Ter a enable_post_data_readingconfiguração desativada causará isso. De acordo com a documentação:

enable_post_data_reading

Desativar esta opção faz com que $ _POST e $ _FILES não sejam preenchidos. A única maneira de ler os pós-dados será através do wrapper de fluxo de entrada php: //. Isso pode ser útil para solicitações de proxy ou para processar os dados POST com eficiência de memória.

Luke A. Leber
fonte
4

Se você estiver postando em um arquivo index.php em um diretório, por exemplo /api/index.php, certifique-se de especificar em seu formulário o diretório completo do arquivo, por exemplo

este

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

OU

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

trabalho.

Mas isso falha

<form method="post" action="/api"> 
</form>
Domingo G Akinsete
fonte
Na verdade, tenho exatamente o oposto. Descobri que /my_urifuncionaria, mas não /my_uri/.
Link14
teve o mesmo problema. parece que apache ou nginx adiciona um redirecionamento de / api para / api /
John Smith
4
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

Ok, isso foi estúpido e estarei me envergonhando em público, mas criei um pequeno script de teste para algo em PHP e quando meu $_POSTarray estava vazio, StackOverflow é o primeiro lugar que procurei e não encontrei a resposta que precisava .

Eu só tinha escrito

<form action="test.php">

e esquecido de especificar o método como sendo POST!

Tenho certeza de que alguém vai rir, mas se isso ajudar alguém que faz a mesma coisa, então eu não me importo! Todos nós fazemos isso de vez em quando!

Ivan
fonte
não posso acreditar que esqueci disso também! Estou tentando um novo servidor, e achei que era algo devido a configuração ... de qualquer forma, obrigado pelo lembrete!
Samuel Aiala Ferreira
4

No meu caso, ao postar de HTTP para HTTPS, o $ _POST vem vazio. O problema era que o formulário tinha uma ação como //example.com. Quando corrigi o url de https://example.com , o problema desapareceu.

Игорь Носков
fonte
1
Acho que é algo relacionado a como o servidor está configurado. Estou tendo os mesmos problemas ao usar GoDaddy como host. Esta solução não resolveu o problema.
acarlstein
Esta solução resolveu meu problema. Eu tive um bom headeach.
gokaysatir
3

mesmo problema aqui!

Eu estava tentando me conectar ao código do meu servidor local via solicitação de postagem no carteiro, e esse problema me fez perder muito tempo!

para quem usa projeto local (por exemplo, carteiro): use seu endereço IPv4 (digite ipconfig em cmd) em vez da palavra-chave "localhost". No meu caso:

antes:

localhost/app/login

depois de:

192.168.1.101/app/login
Ali Shariati
fonte
Postman me deu alguns problemas com valores json raspados que têm aspas ou espaços. Ele espera um formato específico.
Tom Anderson
2

REFERÊNCIA: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

Método POST

Faremos algumas modificações para que o método POST seja usado ao enviar a solicitação ...

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);

Alguns cabeçalhos http devem ser configurados junto com qualquer solicitação POST. Então, nós os definimos nestas linhas ...

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

Com as linhas acima, estamos basicamente dizendo que o envio de dados está no formato de um envio de formulário. Também fornecemos o comprimento dos parâmetros que enviamos.

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

Definimos um manipulador para o evento de mudança de 'estado pronto'. Este é o mesmo manipulador que usamos para o método GET. Você pode usar o http.responseText aqui - insira em um div usando innerHTML (AHAH), eval it (JSON) ou qualquer outra coisa.

http.send(params);

Por fim, enviamos os parâmetros com a solicitação. O url fornecido é carregado somente após esta linha ser chamada. No método GET, o parâmetro será um valor nulo. Já no método POST, os dados a serem enviados serão enviados como argumento da função send. A variável params foi declarada na segunda linha como lorem=ipsum&name=binny- então enviamos dois parâmetros - 'lorem' e 'nome' com os valores 'ipsum' e 'binny' respectivamente.

Chandu
fonte
1

No meu caso, era porque eu estava usando jQuery para desabilitar todas as entradas na página antes de usar jQuery para enviar o formulário. Então mudei meu "desabilitar todas as entradas, mesmo os tipos 'ocultos'":

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

para "desativar apenas as entradas do tipo 'botão'":

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

Isso acontecia para que o usuário não pudesse acidentalmente apertar o botão 'ir' duas vezes e encher nosso banco de dados! Parece que se você colocar o atributo 'disabled' em um formulário do tipo 'oculto', seus valores não serão enviados se o formulário for enviado!

Josh P
fonte
1

Para mim, .htaccess estava redirecionando quando o mod_rewrite não estava instalado. Instale o mod_rewite e está tudo bem.

Especificamente:

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

estava executando.

Martin Fisher
fonte
1

Passei horas resolvendo um problema semelhante. O problema no meu caso era o

max_input_vars = "1000"

por padrão, no php.ini. Tive um formulário realmente enorme sem uploads. php.ini está definido como upload_max_filesize = "100M" e post_max_size = "108M" e certamente não foi o problema no meu caso. O comportamento do PHP é o mesmo para max_input_vars quando excede 1000 variáveis ​​no formulário. Ele retorna uma matriz _POST vazia. Eu gostaria de ter encontrado isso uma hora, e horas atrás.

MyraGe
fonte
1

Eu sei que isso é antigo, mas queria compartilhar minha solução.

No meu caso, o problema estava no meu .htaccess, pois adicionei variáveis ​​para aumentar o limite máximo de upload do meu PHP. Meu código era assim:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

Mais tarde, noto que os valores devem ser xxM e não xxMB e quando mudei para:

php_value post_max_size 50M
php_value upload_max_filesize 50M

agora meu $ _POST retornou os dados normalmente antes. Espero que isso ajude alguém no futuro.

Walid Ajaj
fonte
0

Além da postagem do MRMage:

Tive que definir essa variável para resolver o problema de que algumas $_POSTvariáveis ​​(com uma grande matriz> 1000 itens) desapareceram:

suhosin.request.max_vars = 2500

" request", não " post" era a solução ...

Setzling Itzekocke
fonte
0

Talvez não seja a solução mais conveniente, mas descobri que, se definir o actionatributo form para o domínio raiz, index.php pode ser acessado e obter as variáveis ​​postadas. No entanto, se eu definir um URL reescrito como ação, ele não funcionará.

Rápli András
fonte
0

Isso é parecido com o que @icesar disse .

Mas eu estava tentando postar coisas na minha api, localizada em site/api/index.php, postando apenas site/apiporque é repassada index.phpsozinha. Isso, no entanto, aparentemente causou confusão em algo, pois o meu $_POSTfoi esvaziado na hora. Basta postar site/api/index.phpdiretamente em vez de resolvê-lo.

Victor Häggqvist
fonte
0

Meu problema era que eu estava usando a <base>tag HTML para alterar a URL base do meu site de teste. Assim que removi a tag do cabeçalho, os $_POSTdados voltaram.

Ben
fonte
0

No meu caso (página php no servidor mutualisé da OVH) enctype="text/plain"não funciona ( $_POSTe o correspondente $_REQUESTestá vazio), os outros exemplos abaixo funcionam. `

<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>

`

Mais aqui: method = "post" enctype = "text / plain" não são compatíveis?

PaulH
fonte
0

Eu estava recebendo o seguinte erro do 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"]

Depois de remover minha configuração de segurança do mod para testar, tudo funcionou conforme o esperado. Agora, só preciso modificar minhas regras para permanecer seguro, mas flexível o suficiente para minhas necessidades :)

Lucas
fonte
0

Certifique-se de usar name = " your_variable_name " na tag de entrada.

Por engano, uso id = " your_variable_name ".

Passei muito tempo para pegar o bug.

Frank Hsieh
fonte
0

Certifique-se de que a namepropriedade de cada campo esteja definida.

Isso cria um POST vazio no PHP

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

Mas isso vai funcionar

<input type="text" name="Phone" id="Phone">
Miguel Montes de Oca
fonte
Acho que é algo relacionado a como o servidor está configurado. Estou tendo os mesmos problemas ao usar GoDaddy como host. Esta solução não resolveu o problema.
acarlstein
-1

OK, achei que deveria colocar meu caso aqui .... Eu estava deixando o array post vazio em casos específicos .. O formulário funciona bem, mas às vezes os usuários reclamam que clicam no botão enviar e nada acontece .... Depois de pesquisar um pouco, descobri que minha empresa de hospedagem tem um módulo de segurança que verifica as entradas dos usuários e limpa todo o array de post (não apenas os dados maliciosos) se descobrir. No meu exemplo, um professor de matemática estava tentando inserir a equação: dy + dx + 0 = 0; e os dados foram apagados completamente.

Para corrigir isso, aconselho-o agora a inserir os dados na área de texto como dy + dx + 0 = zero, e agora funciona .... Isso pode economizar algum tempo de alguém ..

Mahmoud Elgabry
fonte
5
Pedir aos usuários que façam concessões para códigos defeituosos não é um ponto inicial.
freeworlder
Não é um código realmente defeituoso, mas você pode considerar um novo provedor de hospedagem. Em alternativa, publique a entrada de uma forma diferente, por exemplo, codificação de URL HTML.
Tom Anderson