私は自分の開発ボックス(Ubuntu/PHP5 +/MySQL5 +)で完全に動作するカスタムCMSを作成しました。
クライアントのプロダクションボックスに移動したところ、すべてのフォーム送信が空の$ _POST配列として表示されるようになりました。
file_get_contents('php://input');
を使用してデータが実際に渡されることを確認するトリックを見つけました。そこでデータは正常に表示されます。$_POST
/$_REQUEST
配列は常に空です。
また、firebug(application/x-www-form-urlencoded; charset=utf-8
)を使用して、content-typeヘッダーが正しいことも確認しました。
この問題は、フォームがAJAXまたは通常のフォーム送信のいずれを介して送信されているかに関係なく発生します。
どんな助けも大歓迎です!
この質問はフォームを介したPOSTに関するものでしたが、JSONコンテンツタイプを使用してPOSTを行う際に同様の問題に対する回答を求めてここに来ました。答えを見つけて、それが私に多くの時間を要したので、それを共有したかったです。
JSON content-typeを使用する場合、$ _ POST配列にはデータが入力されません(マルチパートフォームの場合のみ)
問題を修正するために機能したのは次のとおりです。
$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);
これが誰かを助けることを願っています!
別の考えられる原因があります-私のフォームはWWWなしでdomain.comに送信していました。そして、「WWW」を追加する自動リダイレクトを設定していました。プロセスで$ _POST配列が空になっていました。修正するには、www.domain.comに送信するだけでした。
同様の問題がありました。簡単な修正であることが判明しました。私が持っていた形で
<form action = "directory" method = "post">
ここで、directoryは...ディレクトリの名前です。 POST配列は完全に空でした。ブラウザでURLを見ると、最後にスラッシュが表示されていました。
私のアクションの最後にスラッシュを追加すると、トリックができました-
<form action = "directory /" method = "post">
$ _POST配列が再びいっぱいになりました!
Php.iniで次のことを確認してください。
track_vars
(非常に古いPHPバージョンでのみ使用可能)はOn
に設定されますvariables_order
には文字P
が含まれますpost_max_size
は妥当な値(8 MBなど)に設定されますsuhosin.post.max_vars
およびsuhosin.request.max_vars
は十分な大きさです。私の2番目の提案があなたの問題を解決すると思います。
HTTPからHTTPSに投稿すると、$_POST
が空になることがわかりました。これはフォームのテスト中に発生しましたが、気づくまでしばらくかかりました。
同様の、しかしわずかに異なる問題に遭遇し、問題を理解するのに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がテストされることを疑いました。
うまくいった。
誰かが役に立つと思うように、ここに投稿してください。
/api/index.phpなどのディレクトリにあるindex.phpファイルに投稿する場合は、フォームに完全なディレクトリを指定するようにしてください。
この
<form method="post" action="/api/index.php">
</form>
OR
<form method="post" action="/api/">
</form>
動作します。
しかし、これは失敗します
<form method="post" action="/api">
</form>
この時点ではエレガントな解決策はありませんが、この問題に遭遇した他の人の将来の参考のために私の発見を共有したかったです。問題の原因は、.htaccessファイル内の2つの上書きされたphp値でした。これらの2つの値を追加して、ファイルアップロードのファイルサイズ制限をデフォルトの8 MBからより大きなものに増やしました-デフォルトよりも大きくても小さくても、htaccessファイルにこれらの2つの値があるだけで問題が発生することがわかりました。
php_value post_max_size xxMB
php_value upload_max_filesize xxMB
追加の変数を追加して、すべてのsuhosin.post.xxx/suhosin.upload.xxx変数の制限を引き上げることを望みましたが、残念ながらこの問題には影響しませんでした。
要約すると、ここで「なぜ」を実際に説明することはできませんが、根本原因を特定しました。私の考えでは、これは最終的にはsuhosin/htaccessの問題ですが、残念ながら、上記の2つのphpのオーバーライドされた値を削除する以外に解決できなかった問題です。
私がこれを理解するために数時間を殺したので、これが将来誰かに役立つことを願っています。これを手伝ってくれたすべての人に感謝します(MrMage、Andrew)
enable_post_data_reading
設定を無効にすると、これが発生します。ドキュメントによると:
enable_post_data_reading
このオプションを無効にすると、$ _ POSTと$ _FILESが読み込まれなくなります。ポストデータを読み取る唯一の方法は、php:// inputストリームラッパーを使用することです。これは、リクエストをプロキシしたり、メモリ効率のよい方法でPOSTデータを処理するのに役立ちます。
デフォルトは「text/plain」なので、enctype = "application/x-www-form-urlencoded"を使用して問題を解決できました。 $ DATAをチェックインすると、セパレータは「text/plain」用のスペースと「urlencoded」用の特殊文字になります。
フランクをよろしく
<form action="test.php" method="post">
^^^^^^^^^^^^^
さて、これは愚かで、公の場で恥ずかしい思いをしますが、PHPの何かのテストスクリプトを少しノックアップし、$_POST
配列が空のとき、StackOverflowが最初の場所です見て、必要な答えが見つかりませんでした。
書いただけだった
<form action="test.php">
メソッドをPOST
として指定するのを忘れました!
私は誰かがスニガーするだろうと確信していますが、これが同じことをする他の誰かを助けるなら、私は気にしません!私たちは皆、時々それをします!
ここで同じ問題!
私は郵便配達員の郵便要求を介してローカルサーバーコードに接続しようとしていたが、この問題は私の時間を無駄にした!
ローカルプロジェクトを使用する人(例:郵便配達員):「localhost」キーワードの代わりにIPv4アドレス(cmdでipconfigと入力)を使用します。私の場合:
前:
localhost/app/login
後:
192.168.1.101/app/login
同様の問題を修正するのに何時間も費やしました。私の場合の問題は、
max_input_vars = "1000"
デフォルトでは、php.iniにあります。アップロードなしで本当に巨大なフォームがありました。 php.iniはupload_max_filesize = "100M"およびpost_max_size = "108M"に設定されており、私の場合は問題ではありませんでした。 PHPの動作は、フォーム内の変数が1000個を超えた場合のmax_input_varsと同じです。 _POST配列を空にして返します。私はそれが一時間前、そして数時間前に見つけられたらいいのにと思う。
リファレンス: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php
リクエストを送信するときに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メソッドでは、パラメーターはNULL値になります。ただし、POSTメソッドでは、送信されるデータはsend関数の引数として送信されます。 params変数は、2行目でlorem=ipsum&name=binny
として宣言されました-したがって、2つのパラメーター 'lorem'および 'name'を、それぞれ値 'ipsum'および 'binny'で送信します。
私はこれが古いことを知っていますが、私のソリューションを共有したかったです。
私の場合、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は以前と同じようにデータを返しました。これが将来誰かを助けることを願っています。
私にとっては、mod_rewriteがインストールされていないときに.htaccessがリダイレクトしていました。 mod_rewiteをインストールすると、すべて問題ありません。
具体的には:
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</Ifmodule>
実行していました。
私の場合、jQueryを使用してフォームを送信する直前に、jQueryを使用してページ上のすべての入力を無効にしていたためです。そこで、「「非表示」タイプでもすべての入力を無効にする」を変更しました。
$(":input").attr("disabled","disabled");
「「ボタン」タイプの入力のみを無効にする」:
$('input[type=button]').attr('disabled',true);
これは、ユーザーが誤って「実行」ボタンを2回押してDBをホースアップできないようにするためでした! 「hidden」タイプのフォーム入力に「disabled」属性を設定すると、フォームが送信されても値は送信されないようです!
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"]
テストするためにmodセキュリティ構成を削除すると、すべて正常に機能しました。ルールを修正するだけで、安全でありながら必要に応じて柔軟に対応できます:)
MRMageの投稿に加えて:
いくつかの$_POST
変数(1000個を超える大きな配列を持つ)が消える問題を解決するには、この変数を設定する必要がありました。
suhosin.request.max_vars = 2500
「request
」ではなく「post
」が解決策でした...
私の問題は、HTML <base>
タグを使用して、テストサイトのベースURLを変更していたことです。そのタグをヘッダーから削除すると、$_POST
データが返されました。
これは、@ icesar said に似ています。
しかし、私はsite/api/index.php
にあるapiにコンテンツを投稿しようとしましたが、それはsite/api
にのみ渡されるため、index.php
にのみ投稿していました。ただし、$_POST
がその場で空になったため、これにより明らかに何かが台無しになります。代わりにsite/api/index.php
に直接投稿するだけで解決しました。
入力タグでname = "your_variable_name"を使用していることを確認してください。
誤ってid = "your_variable_nameを使用しています。
バグを見つけるのに多くの時間を費やしました。
私の場合(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>
`
私の場合、HTTPからHTTPSに投稿するとき、$ _ POSTは空になります。問題は、フォームに//example.comのようなアクションがあったことです。URLを https://example.com に修正すると、問題はなくなりました。
おそらく最も便利な解決策ではありませんが、フォームaction
属性をルートドメインに設定すると、index.phpにアクセスして投稿された変数を取得できることがわかりました。ただし、書き換えられたURLをアクションとして設定すると、機能しません。