WioLTEを使用してhttpPOSTによってデータをPHPにアップロードしたいと考えています。
しかしながら、phpでのデータの送信または受信が上手くいってない状況で、色々試してみましたが解決せず詰まっております。
何かご助言いただければ幸いです。
よろしくお願い致します。
やりたいこと
WioLTEからname 属性s0のデータをtest.phpに対して送り、受け取ったらcsvを作り、そのcsvにs0データを書き込む
試してみたこと、できていること
WioLTEボードでサンプルスケッチ「ifttt-webhook」を少し改変し、IFTTTでLINEにメッセージを送るのを試したところ、WioLTE/web通信が問題ないことを確認。
↓
下記のtest.php(データ受取用)とsend.php(test.phpの動作確認用)を作り、test.phpが動作(POST受信⇒CSV作成⇒データ書込)することを確認。
↓
別の3Gモジュール(3GIM)でデータをアップし、test.phpが動作する(CSV作成⇒データ書込)を確認。
↓
WioLTE(下記コード)でデータをアップし、test.phpはCSV作成を作成するが、データ書込がされない。
↓
データのフォーマットをいくつか試してみたがいずれもデータ書込がされない。(CSV作成は作成される。)
考えられる要因
ボードとwebの通信はIFTTTやPOST⇒CSV作成が上手くいっているので、データの受け渡しが上手くいってないのでは?
データを受け取るPHP
test.phpは
・POSTを受け取ったらcsvを作る
・$_POST['s0']で name 属性s0のデータを受け取り、csvに書き込む
確認用のPOST送信PHP
send.php
・test.phpにデータを送るだけのフォーム
<form method="POST" action="test.php">
<input type="text" name="s0"/>
<input type="submit" value="送信"/>
</form>
WioLTEのコード
#include <WioLTEforArduino.h>
#include <stdio.h>
#define APN "soracom.io"
#define USERNAME "sora"
#define PASSWORD "sora"
#define URL "http://***/test.php"
#define INTERVAL (15000)
WioLTE Wio;
void setup() {
delay(200);
SerialUSB.println("");
SerialUSB.println("--- START ---------------------------------------------------");
SerialUSB.println("### I/O Initialize.");
Wio.Init();
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyLTE(true);
delay(500);
SerialUSB.println("### Turn on or reset.");
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to \""APN"\".");
if (!Wio.Activate(APN, USERNAME, PASSWORD)) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Setup completed.");
}
void loop() {
int status;
SerialUSB.println("### Post. ###");
char* dataS1 = "s0=123"; // application/x-www-form-urlencoded フォーマット
char* dataS2 = "\"s0\"=123";
char* dataS3 = "s0=\"123\"";
char* dataS4 = "\"s0\"=\"123\"";
char* dataS5 = "s0:123";
char* dataS6 = "\"s0\":123";
char* dataS7 = "s0:\"123\"";
char* dataS8 = "\"s0\":\"123\"";
char* dataS9 = "{s0:123}";
char* dataS10 = "{\"s0\":123}";
char* dataS11 = "{s0:\"123\"}";
char* dataS12 = "{\"s0\":\"123\"}"; // application/json フォーマット
SerialUSB.print("dataS1 : "); SerialUSB.println(dataS1); if (!Wio.HttpPost(URL, dataS1, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS2 : "); SerialUSB.println(dataS2); if (!Wio.HttpPost(URL, dataS2, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS3 : "); SerialUSB.println(dataS3); if (!Wio.HttpPost(URL, dataS3, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS4 : "); SerialUSB.println(dataS4); if (!Wio.HttpPost(URL, dataS4, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS5 : "); SerialUSB.println(dataS5); if (!Wio.HttpPost(URL, dataS5, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS6 : "); SerialUSB.println(dataS6); if (!Wio.HttpPost(URL, dataS6, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS7 : "); SerialUSB.println(dataS7); if (!Wio.HttpPost(URL, dataS7, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS8 : "); SerialUSB.println(dataS8); if (!Wio.HttpPost(URL, dataS8, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS9 : "); SerialUSB.println(dataS9); if (!Wio.HttpPost(URL, dataS9, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS10: "); SerialUSB.println(dataS10); if (!Wio.HttpPost(URL, dataS10, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS11: "); SerialUSB.println(dataS11); if (!Wio.HttpPost(URL, dataS11, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
SerialUSB.print("dataS12: "); SerialUSB.println(dataS12); if (!Wio.HttpPost(URL, dataS12, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status);
delay(INTERVAL);
}
シリアルモニターの出力
dataS1 : s0=123
Status:200
dataS2 : "s0"=123
Status:200
dataS3 : s0="123"
Status:200
dataS4 : "s0"="123"
Status:200
dataS5 : s0:123
Status:200
dataS6 : "s0":123
Status:200
dataS7 : s0:"123"
Status:200
dataS8 : "s0":"123"
Status:200
dataS9 : {s0:123}
Status:200
dataS10: {"s0":123}
Status:200
dataS11: {s0:"123"}
Status:200
dataS12: {"s0":"123"}
Status:200
追記
test.phpに下記3行を追加し、確認用としてログファイル(log.txt)に時刻と受け取ったデータ($_POST)を書き込むようにしました。
file_put_contents( '***/log.txt', date("Y/m/d H:i:s")."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', print_r($_POST, true)."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "\n", FILE_APPEND | LOCK_EX );
これに確認用のsend.phpからデータ(s0=123)を送信すると
2019/08/16 15:54:28
Array
(
[s0] => 123
)
と書き込まれ、空のデータ(s0=)を送信すると
2019/08/16 15:54:48
Array
(
[s0] =>
)
と書き込まれます。
WioLTEから上記プログラムでデータを送信すると
2019/08/16 15:56:06
Array
(
)
となります。(いろいろなフォーマットで12回送信しているので、これと同じように空の状態で12回書き込まれています。)
これらの結果から、test.phpに送るデータのフォーマット(name要素の指定)が悪いのではないかと考えています。
追記2
httpPOSTする際のContent-Typeには
① application/x-www-form-urlencoded
② application/json
などいくつか種類があるようで、WioLTEのライブラリで使われているhttpPOST関数には
#define HTTP_CONTENT_TYPE "application/json"
との記載(ですので②)があり、今まで試していたのは①のs0=123という書き方だったのでこれが原因ではないかと思います。
application/jsonでのフォーマットで試してみたいと思います。
追記3
application/jsonでのフォーマットは
char* dataS12 = "{\"s0\":\"123\"}";
になると思います。(WioLTEのコードのdataS1からdataS11までは削除)
test.phpに
$json_string = file_get_contents('php://input');
$obj = json_decode($json_string);
file_put_contents( '***/log.txt', date("Y/m/d H:i:s")."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "obj"."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', print_r($obj, true)."\n", FILE_APPEND | LOCK_EX );
を追加・変更すると
2019/08/16 18:03:54
obj
stdClass Object
(
[s0] => 123
)
という結果が得られました!
WioLTEのライブラリのhttpPOST関数では、Content-Typeがapplication/x-www-form-urlencodedではなく、application/jsonだったことが原因でした。
追記4
追記3で今回の目的の趣旨は解決ですが、データが複数の場合の情報も残したいと思います。
と思ったら、連想配列objから個別にデータを取り出せない…
WioLTEのコード
char* dataS = "{\"s0\":\"123\",\"s1\":\"456\"}";
test.php
$json_string = file_get_contents('php://input');
$obj = json_decode($json_string);
file_put_contents( '***/log.txt', date("Y/m/d H:i:s")."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "obj"."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', print_r($obj, true)."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "Data"."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "Data1(s0)=".$obj['s0']."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "Data2(s1)=".$obj['s1']."\n", FILE_APPEND | LOCK_EX );
file_put_contents( '***/log.txt', "\n", FILE_APPEND | LOCK_EX );
結果(log.txt)
2019/08/16 18:43:30
obj
stdClass Object
(
[s0] => 123
[s1] => 456
)
Data
Dataの下に
Data1(s0)=123
Data2(s1)=456
と表示されるはずがされていません…
objに「stdClass Object」という文字列も含まれているから連想配列ではない??
調べてみます。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
まだ回答がついていません
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正の依頼
t_obara
2019/08/13 09:51
正常に期待したデータが受け取れているのか、サーバー側のログは確認されているのでしょうか?それもご提示されるとよろしいかと。
cucco
2019/08/13 22:47
ご指摘ありがとうございます。
ログを確認してみましたところ、アクセスした時間帯にPOSTの履歴がありました。
しかし、データまでの履歴は記載されていませんでした。
あまりログを見慣れていないのですが、受け取ったデータまで確認できるものでしょうか?
t_obara
2019/08/14 10:00
csvファイルが出力されていることから、アクセス履歴があることが確認できたことは状況と符合しています。その後、想定したデータなのかはphpにログを出力するコードを追加するなどをしてご自身で確認すべきです。問題を切り分けする上で必須ですよね?
cucco
2019/08/16 09:37
>>phpにログを出力するコード
こういうものがあるんですね!
error_log()でしょうか。これを使って確認してみたいと思います。
大変勉強になります。ありがとうございます。
cucco
2019/08/16 16:58
お世話になっております。
PHP側でログを残せるようにし、確認してみたところ、アクセスはできているがname要素の指定が正しくできていないようでデータ受け取りができていないようでした。(追記1)
色々調べているうちにPOSTのデータのフォーマットがいくつかあることを知り、少なくとも今まで試していたフォーマットとライブラリで指定されているフォーマットが違うからでは?というところまで来ました。
引き続き、試してみたいと思います。
t_obara
2019/08/19 18:06
json_decodeについて、マニュアルをよくご覧になることをお勧めします。
https://www.php.net/manual/ja/function.json-decode.php