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

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

ただいまの
回答率

89.99%

ajaxを使った、DB情報の更新方法

解決済

回答 4

投稿 編集

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

paccuman

score 2

前提・実現したいこと

php初学者です。
phpで、記事を投稿/検索/新規作成/編集するプログラムを組んでます。

【伺いたい工程部分】
特定のidの記事の表示画面から、idを受け取りその記事を編集するための編集画面での出来事です。
ユーザーには、新しい情報を入れてもらい最後に更新ボタンを押してDB更新を完了してもう仕様です。

【イメージしている流れ】
① ユーザーが新たに入力した値を取得
それぞれ、inputとtextareaのvalueには初期値としてDBから取得した値が入っているのでchangeイベントで、
radioはclickイベントで、ユーザーがブラウザ上で編集して入力している値を確認しvarで変数に代入して値を保持

$(function(){

    //ブラウザ上で更新された、input,textareaのvalueを変数に代入
  $('#id_url').change(function() {
    var $inputVal_url = $(this).val();
  });

  $('#id_wire_url').change(function() {
    var $inputVal_wire_url = $(this).val();
  });

  $('#id_project').change(function() {
    var $nputVal_project = $(this).val();
  });

  $('#id_coment').change(function() {
    var $textareaVal_coment = $(this).val();
  });


    //ブラウザ上で選択された、ラジオボタンのvalueを変数に代入
$(".page_name_btn").click( function() {
    var $radioVal_page_name = $("input[name='style']:checked").val();    
});

$(".job_btn").click( function() {
    var $radioVal_job = $("input[name='style']:checked").val();    
});

$(".style_btn").click( function() {
    var $radioVal_style = $("input[name='style']:checked").val();    
});

② phpに変数を渡す
ajaxで#ajaxクリック時に、update.phpに変数を渡す

   $('#ajax').on('click',function(){

          //idを変数に代入
          var $id_id = $('#id_id').val();

        $.ajax({
          url:'update.php', //送信先
          type:'POST', //送信方法
          datatype: 'json', //受け取りデータの種類
          data:{
          id : $id_id,
          url : $inputVal_url,
          wire_url : $inputVal_wire_url,
          project : $inputVal_project,
          coment : $textareaVal_coment,
           page_name :$radioVal_page_name,
           job :$radioVal_job,
           style :$radioVal_style
          },
          // Ajax通信が成功した時
          success : function(){
            alert('更新されました。\nありがとうございました。');
          console.log('通信成功');
          },
          // Ajax通信が失敗した時
          error : function() {
            alert('通信に失敗しました。\n通信環境を確認の上、もう一度更新ボタンを押してください。');
          console.log('通信失敗');
        }
         }); 
         //submitによる画面リロードを防いでいます。
         return false;
    }); //#ajax click end

③ DBを更新する
update.phpで、sql実行して値を更新

ini_set("display_errors", 1);
error_reporting(E_ALL);

//受け取った値を代入
$id = $_REQUEST['id'];
$project = $_REQUEST['project'];
$url = $_REQUEST['url'];
$wire_url = $_REQUEST['wire_url'];
$page_name = $_REQUEST['page_name'];
$job = $_REQUEST['job'];
$style = $_REQUEST['style'];
$coment = $_REQUEST['coment'];


$pdo = new PDO(//接続情報);

$sql = 'UPDATE articles SET project = :project and url = :url and wire_url = :wire_url and page_name = :page_name and job = :job and style = :style and coment = :coment
        WHERE id = :id
        ';
        $statement = $pdo->prepare($sql);
        $statement->bindValue(':id', $id, PDO::PARAM_INT);
        $statement->bindValue(':project', $project, PDO::PARAM_STR);
        $statement->bindValue(':url', $url, PDO::PARAM_STR);
        $statement->bindValue(':wire_url', $wire_url, PDO::PARAM_STR);
        $statement->bindValue(':page_name', $page_name, PDO::PARAM_STR);
        $statement->bindValue(':job', $job, PDO::PARAM_STR);
        $statement->bindValue(':style', $style, PDO::PARAM_STR);
        $statement->bindValue(':coment', $coment, PDO::PARAM_STR);
        $statement->execute();

    $statement = null;
    $pdo = null;

(補足)

<form>
ajaxのクリックイベント部分のhtmlの記述
<!--input,textarea,radioの入力コードの記述-->

<input id="ajax" class="update-btn" type="submit" value="更新する">
</form>

発生している問題・エラーメッセージ

DBの更新がされず、ajax通信も成功しているのかが不明です。。。

申し訳ございません。ブラウザが更新されるだけで特に変化なしです。

試したこと

ググりました。
jqueryの変数をphpに渡すことと、その中でajaxを調べ、上記のソースコードはググりながらコピペしてカスタムしました。

補足情報(FW/ツールのバージョンなど)

php:5.7
mysql:5.7.28

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2019/12/01 04:33

    >php初学者です。
    あまりこういった但し書きは要らないと思います(要件ではないので)
    「初心者アイコン」を質問につけるにとどめてください。
    質問は編集できます。

    キャンセル

  • paccuman

    2019/12/01 19:12

    ありがとうございます。編集しました。

    キャンセル

回答 4

checkベストアンサー

+2

DBの更新がされず、

まずSQLのミスがありますね。それは既に指摘がある通り。

ただ、SQLはPHPからすると外部の仕組みです。
絶対にPHPからしか実行できないわけではありません。
他の言語からも実行できますし、ターミナルやツールなどからログインして直接実行することも出来ます。

直接実行して想定通りに動かないSQLであれば当然PHPなど外部から実行しても動きません。
変数など入力を受け付ける可変な情報はひとまず固定値にして直接実行して想定通りの結果が得られるか確かめてから、利用しましょう。
そうすることで、何か問題が起きても「SQLの構文自体は問題ない」と、1つ可能性を潰せるからです。

いきなりPHPから変数(やプリペアドステートメント)で実行してしまうと、
PHPのコードがいけないのか、SQLがいけないのか、値がきちんとPHPから渡せていないのか、通信状態が悪いのか、、、、、様々な可能性と向き合わなければいけません。
1つでも可能性を潰しておけば、考慮すべき部分が減るので、確かめやすくなります。

ajax通信も成功しているのかが不明です。。。 

通信自体の成否やPHP側の出力はJavaScript側で取得可能です。

jQueryリファレンスなどを確認されると分かりますが、様々な引数が返ってくることが分かります。

success
Type: Function( Anything data, String textStatus, jqXHR jqXHR )
error
Type: Function( jqXHR jqXHR, String textStatus, String errorThrown )

successにきたとしてもtextStatusは必ず確認しておいたほうが良いです。
ちなみに受け取る側の引数なので必須ではありません。
が、これだけ返してくれるのでなるべく全て見ておくようにしておいたほうが良いでしょう。
alert()などで直接画面に出す必要はなく、console.log()でコンソールに出すだけでも良いです。
※もしユーザー向けに本番リリースするのであれば除くべき

AjaxではPHP側での出力をsuccessの「data」で拾ってくれる仕組みがあるので、何かしら出力するようにして置いた方が良いです。
別に1とか0とかでも良いです。何も返してないことで、余計にPHP側の状況を不明にしてしまっています。

また、PHP側にDBの処理をさせるのであれば、エラーを捕捉する仕組みを導入すべきです。

try{

//PDO接続からトランザクション、DB処理、コミット/ロールバックまで

}catch (PDOException $e){
  echo $e->getMessage();
  //できれば$e全部ログ出力
}


PHPマニュアル:エラーおよびエラー処理

さらっと最後に書きましたが、Ajaxもデバッグできるような仕組みを導入しましょう。
ブラウザのデベロッパツールでも通信状態を確認することができますし、
PHPコードがどこまで通っているか確かめたかったらテキストファイルに状況を書きだすでも良いですし、デバッガ導入も有効でしょう。
私としてはAjax実行するといっても結局POST/GETでリクエストを送るにすぎないので、JavaScriptからでなく普通にform送信でPOST/GETリクエストを送るのが結構手っ取り早い気もします。ブラウザで見れますしね。

蛇足:
success/errorは割と古めの書き方として認識されています。
本件落ち着きましたら、新しい書き方もチャレンジしてみましょう。
おじさんが若い時はね$.ajax()のオプションでsuccessとかerrorとか指定していたんだよ(追憶)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/12/01 20:19

    ありがとうございます!
    トランザクションやコミットや色々「できているのか」「できていないのか」を判定する記述は大切なんですね。。
    success/errorについての補足情報もありがとうございました!
    ご指摘いただいたように動かない可能性が複数あるので確認し、
    おそらく、質問文でいうところの【① ユーザーが新たに入力した値を取得】に問題ありでした。


    (確認したこと)
    >sql
    SETの記述を修正し、更新するデータは変数ではなく、文字列や整数で検証し、UPDATEできたためコード上はとりあえず成功

    >ajax
    通信先のupdate.phpに1をechoさせ、それをscriptを記述しているファイルでdataで受け取れりalertできたため通信も成功

    >var変数について
    無関係な別の文字や数値をvar変数に入れて通信したところ更新できました
    (質問文でいうところの【① ユーザーが新たに入力した値を取得】に問題あることが判明)

    キャンセル

  • 2019/12/01 20:29

    ブラウザで変更があった際にvalueを取得する7個のvarを、console.logで見ましたが全て正常に値が入ってました。
    (すみません、【① ユーザーが新たに入力した値を取得】のソースコードにタイプミスがありました)

    ただ、この方法で値を代入したvarをajaxで送ろうとすると、また、ブラウザだけ更新される現象になってしまいます。
    現状、ここが原因かと思うのですが、なぜこのようなことが起こるかわかりますでしょうか?

    キャンセル

  • 2019/12/02 06:27

    「ブラウザだけ更新」とはどういう挙動を想定された表現ですか?

    キャンセル

  • 2019/12/02 16:52 編集

    画面の情報は変わらず、ただF5を押したような挙動です。

    キャンセル

+1

質問に CREATE TABLE文は提示しましょう。
SQLのところだけ、
理解し易いように改行しています。

UPDATE articles SET
    project = :project 
and url = :url 
and wire_url = :wire_url
and page_name = :page_name 
and job = :job 
and style = :style 
and coment = :coment
WHERE id = :idUPDATE articles SET
    project = :project 
  , url = :url 
  , wire_url = :wire_url
  , page_name = :page_name 
  , job = :job 
  , style = :style 
  , coment = :coment
WHERE id = :id


同じSQLでもデータベースやそのバージョンによって方言が大きいですから、どのデータベースを使うのかを質問のタグで示したり、バージョンも明記した方が適切なコメントが付き易いです。SQLの観点から Oracle Database, PostgreSQL, MySQL の特徴を整理しよう!

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/12/01 19:19 編集

    ありがとうございます。
    修正し、とりあえず更新する情報は変数ではなく、仮の文字列や整数で検証し、
    無事UPDATEすることができました!
    (mysqlのバージョンも追加しました)

    キャンセル

+1

PHP は既に回答があるので JavaScript について。
function はスコープを形成するので変数は反映されず送信されていません。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions

変更のたびに取得する理由もなさそうなので .ajax() の直前で取得すればいいでしょう。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/12/02 18:36

    ありがとうございます。
    たしかに、function内なので外では呼び出せないのですね。。!

    ちなみに、.changeや.clickイベントの処理結果を戻り値として受け取ることで、
    ajaxで送るデータとして活用できるようになると思っていますが、あっていますでしょうか?

    調べてみたのですが明確な記述方法が見つからず、
    returnの記述をどのように書けばよいかお判りでしょうか?

    キャンセル

  • 2019/12/03 14:59

    ありがとうございます。
    整理してまた別の質問として投稿させていただきます。!
    また、よろしくお願いいたします。

    キャンセル

0

DBの更新がされず、ajax通信も成功しているのかが不明です。。。 

上記に関してのみ。
ajax のデバッグでは、ブラウザの開発ツール使用して、リクエストとレスポンスを確認すると良いですよ。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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