質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.98%

WioLTE にhttpPOSTによるアップロードについて。

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 194

cucco

score 9

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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • 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

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる