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

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

ただいまの
回答率

87.59%

pdoでデータベースに更新されない

解決済

回答 3

投稿 編集

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

score 13

前提・実現したいこと

jqueryでjson型のデータschedules, trip_idをpostしています。


"trip_id" : "";
"schedules" : {"0":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]},
"1":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]},
"2":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]}}

このデータをつかってpdoで一行ずつinsertしているのですがデータベースには更新されず、エラーメッセージも表示されません。
原因がわかる方教えてください。

該当のソースコード

$insert_sql = 'insert into schedule (trip_id, start_time, destination_name, required_time, lat, lng, kind) '.
        'values(:trip, :start, :name, :time, :lat, :lng, :kind)';

try {
$schedules = $_POST['schedules'];
$trip_id = $_POST['trip_id'];

$dbh = new PDO($dsn, $dbUser, $dbPass);
$stmt = $dbh->prepare($insert_sql);

foreach ( $schedules as $count ) {

    $stmt->bindValue(':trip',intval($trip_id), PDO::PARAM_INT);
    $start_time = new DateTime($count['startTime']);
    $start_time = $start_time->format('Y-m-d H:i:s');
    $stmt->bindParam(':start',$start_time, PDO::PARAM_STR);
    $stmt->bindParam(':name',$count['name'], PDO::PARAM_STR);
    $stmt->bindValue(':time',intval($count['requiredTime']), PDO::PARAM_INT);
    $stmt->bindParam(':lat',$count['lat'], PDO::PARAM_STR);
    $stmt->bindParam(':lng',$count['lng'], PDO::PARAM_STR);
    $stmt->bindParam(':kind',$count['kind'], PDO::PARAM_STR);


$stmt->execute();

$stmt = null;
$dbh = null;

}catch (PDOExceaption $e) {
   err_log($e->getMessage());
   header('Content-Type: text/plain; charset=UTF-8', true, 500);
   exit();
}
}
function insertSchedules(){
    "trip_id" : "";
   "schedules" : {"0":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]},
                  "1":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]},
                  "2":{"startTime":[],"name":[],"requiredTime":[],"lat":[],"lng":[],"kind":[]}};

    var sendSchedules = JSON.stringify(schedules);
    var json = $.parseJSON(sendSchedules);

    $.ajax({
        type: "POST",
        url: "insertSchedules.php",
        datatype: "json",
        data:{
          'schedules': json,
          'trip_id' : 1
        },
    }).done( (data) => {
            console.log(data);
            return data;
    })
    .fail( (data) => {
        console.log(data);
    })
    .always( (data) => {
    });
}

試したこと

dateTime型をバインドするところでエラーが出ていたので、その部分を直していたらエラーメッセージは消えたのですが、
更新はされない状態になりました。
ご指摘にあったとおりにjson_decodeにデータを通してみたところ
$post_array = json_decode($schedules,true);

<b>Warning</b>:  json_decode() expects parameter 1 to be string, array given in <b>/var/www/html/koba/plover/dao/insertSchedules.php</b> on line <b>53</b><br />

<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/var/www/html/koba/plover/dao/insertSchedules.php</b> on line <b>61</b><br />
が表示されてしまいました。

var_dump($_POST);の結果は以下です。

array(2) {
  ["schedules"]=>
  array(3) {
    [0]=>
    array(6) {
      ["startTime"]=>
      string(19) "YYYY-mm-dd hh:mm:ss"
      ["name"]=>
      string(9) "***"
      ["requiredTime"]=>
      string(1) "0"
      ["lat"]=>
      string(9) "00.000000"
      ["lng"]=>
      string(9) "000.000000"
      ["kind"]=>
      string(4) "**"
    }
    [1]=>
    array(6) {
      ["startTime"]=>
      string(19) "YYYY-mm-dd hh:mm:ss"
      ["name"]=>
      string(12) "****"
      ["requiredTime"]=>
      string(2) "60"
      ["lat"]=>
      string(9) "00.000000"
      ["lng"]=>
      string(10) "000.000000"
      ["kind"]=>
      string(0) ""
    }
    [2]=>
    array(6) {
      ["startTime"]=>
      string(19) "YYYY-mm-dd hh:mm:ss"
      ["name"]=>
      string(13) "******"
      ["requiredTime"]=>
      string(2) "30"
      ["lat"]=>
      string(9) "00.000000"
      ["lng"]=>
      string(10) "000.000000"
      ["kind"]=>
      string(4) "****"
    }
  }
  ["trip_id"]=>
  string(1) "1"
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • kunai

    2019/01/29 15:28

    sendScheduleとscheduleでラベルが違ってますが、コピペミスですか?

    キャンセル

  • conchel1989

    2019/01/30 10:57

    コピペミスでした。すいません。

    キャンセル

回答 3

+3

エラーを表示させるところから始めると良いですよ

error_reporting(-1);
ini_set('display_errors', 'On');

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

ざっと眺めた感じ、この辺が怪しいです。
一度修正して動作を確認してみてください。

jqueryでjson型のデータschedules, trip_idをpostしています。

ふむふむ

$schedules = $_POST['schedules'];

キー値ちがうくね?

またPHPがWebサーバとしてPOST通信を受け取った時、
全ての値は文字列として受け取る事になります。

foreachが対応しているのは配列等のループに使えそうなものだけですが、
流石に文字列をそのまま突っ込んで動くわけがありません。
json_decodeなりでJSON文字列をPHPの値にしてください。

$stmt->bindParam(':name',$count['name'], PDO::PARAM_STR);

これはPDO初心者あるある
$stmt->bindParam$stmt->bindValueの違いはわかりますか?

私は違いがわかりますが、
まぁ普通にbindParamのへんてこな仕様を使いこなせる人は限られていますし、
可読性を犠牲にしてでも速度がほしい!みたいな場面でしか使ってはいけません。

という訳で私はbindValue一択だと思っていますし、bindParam警察しています。
よほどの事がない限りbindValueの方を使うようにしてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/29 16:20 編集

    あらら、飛び火しちゃいましたかすみません。
    でも結構bindParam使ってるけどエラーが出ないから使い続けてるみたいな人多いんですよね。
    mtsさんもお気をつけ下さい、ヤツはループ文の中では使ってはいけない変態仕様です。

    キャンセル

  • 2019/01/29 16:23

    比較記事と副作用見て納得しました。勉強になりました。

    キャンセル

  • 2019/01/30 15:42

    ご回答ありがとうございます。
    schedulesのコピペミスをしていました。
    json_decodeを試したのですが、エラーが出ました。(質問を編集させていただいたのでそちらに詳しいエラーを記述しました)習得した値はすでにphp配列になっていたのではないかと思います。
    bindの使い分けは全く理解していませんでしたので、ご指摘通りbindValueを使うようにしました!

    キャンセル

+2

きちんとtry-catchすればエラーが拾えるかもしれません

try{
  $dbh = new PDO($dsn, $user,$password);
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  $stmt = $dbh->prepare($sql);
  /*bindParam処理*/
  $stmt->execute([]);
}catch(PDOException $e){
  die($e->getMessage());
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

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

関連した質問

同じタグがついた質問を見る