2018-12-21
一部のPOSTデータが受け取れない

以下の環境下で不可思議な事象を経験したので、参考までに残します。
どちらかというと古い環境+name属性の特殊なケースなので遭遇することはほとんど無いと思います
PHP Version 5.1.6
Server API Apache 2.0 Handler
Apache Version Apache/2.2.3 (CentOS)
Apache API Version 20051115
事象としては、
<input type="file" name="abc[0]">
<textarea name="abc[0]">
と、同じnameでPOSTしたときに、textareaの値が$_POSTにセットされなくなる。
もしかしてサーバー側に正しくPOSTされていないかと思い、HTTPのBODYを出力してみると問題なく送信されていました。
input type="file" にファイルをセットしても、しなくても全く同じ事象です。
ファイルをセットした場合は$_FILESにはアップロードされたファイルがセットされています。
色々試してわかったことは、この順番を変えるとfileもtextareaも正しくセットされて取得することが可能でした。
<textarea name="abc[0]">
<input type="file" name="abc[0]">
とtextareaを先にすることで正しく機能する。
で、結局対処としてはUIの関係からこの順番を変えることができないのでJavaScriptでsubmitイベント時に順番を変更してPOSTするようにしました。
通常はname属性の名前を同じにすることは無いですよね。
例えば以下のようにするでしょう。
<input type="file" name="abc_file[0]">
<textarea name="abc_text[0]">
対策としては当然書き換えようかと思いましたが、この名前から色々操作しているため、かなりの修正作業になるため、諦めました。
また、利用サーバーへのSSHログインが可能で,CコンパイラもGNUコンパイラが利用できたので、
POSTデータの調査用プログラムを書きました。
なぜかというとPHPでHTTPのBODYが取得できなかったからです。
http://php.net/manual/ja/wrappers.php.php
に
”php://input は、 enctype="multipart/form-data" に対しては使用できません。”
と記載がありPOSTデータの検証が出来なかった為です。
参考までにBODY出力のC言語ソースを記載します。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* environ */
int main(int argc, char** argv)
{
extern char **environ;
char **env = environ;
char *p;
char txt[4096];
printf("Content-Type: text/plain; charset=UTF-8\n\n");
puts("[環境変数]");
while(*env) {
const char *val;
val = *env;
if (val) {
printf("%s\n", val);
}
env++;
}
printf("\n");
p = getenv("CONTENT_LENGTH");
printf("[CONTENT_LENGTH]\n%s octet\n\n[BODYのデータ]\n",p);
while(fgets(txt,4096,stdin)){
printf("%s",txt);
}
return 0;
}