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のコード
C++
1#include <WioLTEforArduino.h> 2#include <stdio.h> 3 4#define APN "soracom.io" 5#define USERNAME "sora" 6#define PASSWORD "sora" 7 8#define URL "http://***/test.php" 9 10#define INTERVAL (15000) 11 12WioLTE Wio; 13 14void setup() { 15 delay(200); 16 17 SerialUSB.println(""); 18 SerialUSB.println("--- START ---------------------------------------------------"); 19 20 SerialUSB.println("### I/O Initialize."); 21 Wio.Init(); 22 23 SerialUSB.println("### Power supply ON."); 24 Wio.PowerSupplyLTE(true); 25 delay(500); 26 27 SerialUSB.println("### Turn on or reset."); 28 if (!Wio.TurnOnOrReset()) { 29 SerialUSB.println("### ERROR! ###"); 30 return; 31 } 32 33 SerialUSB.println("### Connecting to \""APN"\"."); 34 if (!Wio.Activate(APN, USERNAME, PASSWORD)) { 35 SerialUSB.println("### ERROR! ###"); 36 return; 37 } 38 39 SerialUSB.println("### Setup completed."); 40} 41 42void loop() { 43 44 int status; 45 46 SerialUSB.println("### Post. ###"); 47 48 char* dataS1 = "s0=123"; // application/x-www-form-urlencoded フォーマット 49 char* dataS2 = "\"s0\"=123"; 50 char* dataS3 = "s0=\"123\""; 51 char* dataS4 = "\"s0\"=\"123\""; 52 char* dataS5 = "s0:123"; 53 char* dataS6 = "\"s0\":123"; 54 char* dataS7 = "s0:\"123\""; 55 char* dataS8 = "\"s0\":\"123\""; 56 char* dataS9 = "{s0:123}"; 57 char* dataS10 = "{\"s0\":123}"; 58 char* dataS11 = "{s0:\"123\"}"; 59 char* dataS12 = "{\"s0\":\"123\"}"; // application/json フォーマット 60 61 62 SerialUSB.print("dataS1 : "); SerialUSB.println(dataS1); if (!Wio.HttpPost(URL, dataS1, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 63 SerialUSB.print("dataS2 : "); SerialUSB.println(dataS2); if (!Wio.HttpPost(URL, dataS2, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 64 SerialUSB.print("dataS3 : "); SerialUSB.println(dataS3); if (!Wio.HttpPost(URL, dataS3, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 65 SerialUSB.print("dataS4 : "); SerialUSB.println(dataS4); if (!Wio.HttpPost(URL, dataS4, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 66 SerialUSB.print("dataS5 : "); SerialUSB.println(dataS5); if (!Wio.HttpPost(URL, dataS5, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 67 SerialUSB.print("dataS6 : "); SerialUSB.println(dataS6); if (!Wio.HttpPost(URL, dataS6, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 68 SerialUSB.print("dataS7 : "); SerialUSB.println(dataS7); if (!Wio.HttpPost(URL, dataS7, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 69 SerialUSB.print("dataS8 : "); SerialUSB.println(dataS8); if (!Wio.HttpPost(URL, dataS8, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 70 SerialUSB.print("dataS9 : "); SerialUSB.println(dataS9); if (!Wio.HttpPost(URL, dataS9, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 71 SerialUSB.print("dataS10: "); SerialUSB.println(dataS10); if (!Wio.HttpPost(URL, dataS10, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 72 SerialUSB.print("dataS11: "); SerialUSB.println(dataS11); if (!Wio.HttpPost(URL, dataS11, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 73 SerialUSB.print("dataS12: "); SerialUSB.println(dataS12); if (!Wio.HttpPost(URL, dataS12, &status)){SerialUSB.println("### ERROR! ###");} SerialUSB.print("Status:"); SerialUSB.println(status); 74 75 76 delay(INTERVAL); 77}
シリアルモニターの出力
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」という文字列も含まれているから連想配列ではない??
調べてみます。