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

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

ただいまの
回答率

88.81%

ajaxを使った処理がうまく反映されない

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,273

Beronika

score 18

現在、ajaxを用いて、入力されたデータをデータベースに保存して、別の部分に反映させるというプログラミングを書いております。
プログラミングを書き進めて、実際にデータベースにデータを格納することはできました。しかし、その後、json形式にしてデータを反映させる処理ができません。お時間を取らせてしまい申し訳ありませんが、ここさえ解決すると一気に進めそうなので協力の方をお願いいたします。

ソースコードは下です。わかりやすいように簡易版でまとめます。

ソースコード

$("#registration").on('click',function(){
    $.post('_Ajax.php',{
      dataType:'json',
      name:$('#name').val(),
      url:$("#url").val(),
      mode:'reg'
    }).done(function(res){
      console.log("こんにちは!");
    }).fail(function(XMLHttpRequest, textStatus, errorThrown){
      console.log('失敗');
      console.log("XMLHttpRequest : " + XMLHttpRequest.status);
      console.log("textStatus     : " + textStatus);
      console.log("errorThrown    : " + errorThrown.message);
    });
  });
//jsから渡ってきた値を処理するコード。今回はPHP・Aとする
<?php
require_once('management.php');

$ajax_processing = new DB();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  try {
    $res = $ajax_processing->post();
    header('Content-Type: application/json');
    echo json_encode($res);
    exit;
  } catch (Exception $e) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    echo $e->getMessage();
    exit;
  }
}
//classについて記入しているコード。今回はPHP・Bとする
//一応POSTメソッドを記入。データベースの読み込み等は省略します。
<?php
    class DB{
   public function post(){
      switch ($_POST['mode']){
        case 'reg';
          return $this->registration();
      }
    }


    public function registration(){
      $sql =  "insert into deck_data(name,leader,type,url) values (:name,:leader,:type,:url)";
      $stmt = $this->_db->prepare($sql);
      $stmt->execute(array(
        ":name"=>$_POST['name'],
        ":url"=>$_POST['url']
      ));

      return[
        'id' => $this->_db->lastInsertId()
      ];
    }

自分で行ったこと

ここの部分では、どのような流れで上記のコードになったのかを説明していきます。

1、原因解明
データベースにデータは入力されているので、
・   $res = $ajax_processing->post();
の部分まではうまく行っていると思った。その後の部分に問題があると思い、done(res)以降を「console.log("こんにちは!");」に変更。結果、「こんにちは」は返ってこなかった。fail処理を用意してみたら、failに書いた処理の方が反映された。
→やはりjson形式でうまく返せていないことを確認した。json書き方自体に問題があると分析した。

2、値を代入してみる
そもそもjson形式にする値がないのではないかと仮定した。なので、以下のコードを「$res = $ajax_processing->post();」の上に入れてみた。
$data = array(
"name" => $_GET["name"],
"url" => $_GET['url']
);
結果はターミナルで立てたビルドインサーバーの方に「PHP Notice:  Undefined index: name in (データの場所)」というエラーメッセージが出てきた。
→どうしてnameが定義されていないのか理解できなくなり、余計混乱してくる。
※これは「_GET」を「_POST」に変更するだけで大丈夫でした。

3、エラーの検証(未解決)
そもそもエラーが何かを知りたくなったので、エラーを検出するコードをネットから拾って、入力。結果は下になった
・   textStatus     : parsererror
・   errorThrown    : Unexpected token < in JSON at position 2
どうやらjsonの中にHTMLの形で入ってしまっている?JSONの値の中に「<」というものがあって、それが混乱を招いているということがわかった。
→しかし、json形式で返しているし、どのようにすると「<」取り除かれるのかわからない。どこを改善すればいいのかがわからなくてお手上げ状態。

4、あるサイトを参考(未解決)
ajaxではまった話」こちらのサイトを参考に
echo $res->request->is(['ajax']); …①
を、$this=$ajax_processingの部分に入れてみた。結果、「こんにちは」とは表示された。しかし、「console.log('こんにちは')」の下に「console.log(data)」を入れてみると、「Using $this when not in object context」というエラーが出てしまう。①が結局何かもわからない

主にわからないこと

・そもそもjsで最初に定義した値(「name」や「mode」など)はPHP・Aではどのように使われて、どのようにjson形式で返せばいいのかが理解できない(未解決)
・$resとは何をしているものなのか。そしてjson形式で返ってきた後のdoneで使われているresは同じものなのか、それとも違うものなのか?(解決!今は考えなくて良い)
・json形式から返ってきた際のfunctionの引数が人によって「data」だったりするが、ここに入れる引数はどのようなものなのか?(上に同じ)
・現状どのような問題があってdoneに行けないのか

その他必要な情報があれば随時追記していきます。ajaxの仕組みで理解できていない部分がいくつかあるため、今回のようなミスをしてしまったかもしれないです。もし、ここが理解できていないという部分がありましたら教えていただける人も募集いたします。
お時間を取らせてしまうようですが、よろしくお願いいたします。

※$.postの部分に入れるdataについて
現在、ajax処理を行うために$.postを用いている。そこに「name」と「url」というものがそれぞれあるが、これらをdataに入れた方がいいことは理解している。
しかし、dataにしてしまうとデータベースに反映されなくなってしまう。
なので、現状はこのような形にしているが、もしdataに入れる方法がわかるのであれば教えて欲しいです。
コード
$.post('_Ajax.php,{
data:{
name:name,
url:url
},
mode:"reg",
})~
結果
undifined index:name (場所(PHP・Bの":name"=>$_POST['name'],))
undifined index:name (場所(PHP・Bの))

旧ソースコード(こちらは参考にしなくても結構です。)

$("#registration").on('click',function(){
    var name = $('#name').val();
    var url = $("#url").val();
    $.post('_Ajax.php',{
      dataType:'json',
      name:name,
      url:url,
      mode:'reg'
    }).done(function(res){
      console.log("こんにちは!");
    }).fail(function(XMLHttpRequest, textStatus, errorThrown){
      console.log('失敗');
      console.log("XMLHttpRequest : " + XMLHttpRequest.status);
      console.log("textStatus     : " + textStatus);
      console.log("errorThrown    : " + errorThrown.message);
    });
  });
//jsから渡ってきた値を処理するコード。今回はPHP・Aとする
<?php
require_once('management.php');

$ajax_processing = new DB();

//今回はmanagementクラスのインスタンスを作って、post()というメソッドを呼び出す処理を書いている
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  try {

    $res = $ajax_processing->post();//PHP・Bに飛ぶようにプログラミング
    // jsonであることを知らせている
    header('Content-Type: application/json');
    echo json_encode($res);
    exit;
  } catch (Exception $e) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    echo $e->getMessage();
    exit;
  }
}
//classについて記入しているコード。今回はPHP・Bとする
//一応POSTメソッドを記入。データベースの読み込み等は省略します。
<?php
    class DB{
   public function post(){
      switch ($_POST['mode']){
        case 'reg';
          return $this->registration();
      }
    }


    public function registration(){
      $sql =  "insert into deck_data(name,leader,type,url) values (:name,:leader,:type,:url)";
      $stmt = $this->_db->prepare($sql);
      $stmt->execute(array(
        ":name"=>$_POST['name'],
        ":url"=>$_POST['url']
      ));

      return[
        'id' => $this->_db->lastInsertId()
      ];
    }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Beronika

    2019/05/23 09:48

    自分のミスです。もともと4つの項目があったのですが、よりシンプルにするために2つにしました。
    コードを修正いたします。

    キャンセル

  • mepon

    2019/05/27 22:45

    まだ解決していらっしゃらなかったんですね。
    追記分を見ました。
    console.logの件については「res」で受け取っているのに「data」だと何も出ないのは当然かと思います。
    is~~についてはリクエストが非同期通信であるかどうかの確認です。
    ですのであまり関係ないと言えばないかと。
    以下お願いです。
    ①コードは最新のものに更新してください。(できれば元のソースもそのままで)
    ②postデータをdataに格納して送信して失敗した時のコードも提示してください。

    キャンセル

  • Beronika

    2019/05/28 08:54

    承知いたしました。
    編集いたします。

    キャンセル

回答 6

+3

dataがないから送信してないのではないかと。
とはいえ、typeとかurlとかどこからくるデータなのかなってのは懸念事項としてあるので、
そこはご随意に。

    $.post('_Ajax.php',{
      dataType:'text',
      data: {
        name:name,
        leader:leader,
        type:type,
        url:url,
        mode:'reg'
      }


私が参考にするやり方:
JavaScript(jQuery)からPHPのAPIを利用する - Qiita

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/22 11:37

    実際に試してみました。
    するとconsoleから以下のエラーメッセージが
    「PHP Notice: Undefined index: name in (場所)」
    nameの部分が定義されていないとなっています。

    formは別のファイルに書いています。htmlを用いて、formを使って
    <form>
    <input id = "name" type = "text">
    <input id = "url" type = "text">
    </form>
    <div id = "registration">登録</div>
    という感じです。

    キャンセル

  • 2019/05/22 12:12

    そのコメントは、「ここから先はどうしていいかわからないのでデバッグに最後まで付き合ってくれませんか」とおっしゃっているように受け取れますが、相違ありませんか? ここはペアプログラミングまでしなきゃいけない場ではないと思っていたのだけど。
    POST送信できて、データの送信はJSON形式を使って、PHP側もJSONをデコードして処理した結果をJSON形式で返すようにすれば、大概うまくいきます。
    jQueryからtext形式で送ることができても、phpから応答するデータをjQuery側で処理しやすい形がJSON形式であるべきなので、であれば送信するときもJSONでやればって。
    (今は業務忙しいので、他の方の回答で進められそうならそっちに乗っかってください。)

    キャンセル

+1

POSTするにはjqueryの仕様に沿った書き方が必要です。
リンク先見ればわかるけど、以下のサンプルコードが書いてあります。dataの部分がパラメーターを書くところです。

$.ajax({
  type: "POST",
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

・doneの部分に行くためにはどのようにすればいいのか

リクエストに成功すること(レスポンスをうけとること)

・json形式から返ってきた際のfunctionの引数が人によって「data」だったりするが、ここに入れる引数はどのようなものなのか?

そういうお作法だと思って気にしなくていいです
自力で難しめのjavascript書けるようになった頃にはわかると思うので

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/22 11:26

    回答ありがとうございます。
    ・書き方について
    $ajaxでも試したのですが、余計混乱してしまったこと、ドットインストールでは$postを利用していたため、ドットインストールで習った書き方にしました。
    ネット上ではpostの書き方でも問題がないと書いていましたが、ajaxにするメリットがあるのでしょうか?
    ・doneの部分に行くためには…
    申し訳ございません。説明が少なすぎました。doneに行く方法はわかります。現状のどこが間違えていて、リクエストに失敗しているのかについて知りたいです。
    ・json形式から…
    ありがとうございます。では、ここには何を入れてもいいということなのでしょうか?(現状のresでも、引数の文字を変えてdataにしても大丈夫なのか?)

    キャンセル

  • 2019/05/22 11:34

    $.postでもいいですよ、リンク先の下の方に書き方書いてありますよ。
    個人的な考えですが一番大きなメリットは、公式が前面に出しているお作法を真似できるってことです。公式ドキュメントでは$.ajaxの書き方を優先して書いてますよね?同じ結果を出せるやり方で一番最初に書いてあるぐらいだし。
    dataにしてもいいです。むしろ公式の真似してdataにした方が比較確認しやすいでしょう。
    どこが間違えているかですが、もっとも初歩的なやり方としてtry~catchはせずに1ステップ毎にechoしていけばいいでしょう。処理が途中で止まってるかどうか分かるでしょ?

    キャンセル

  • 2019/05/22 11:45

    把握ミスでした。ありがとうございます。
    メリットの回答もありがとうございます。

    まずは1つずつのステップで解決していこうと思います。わかり次第、詰り次第質問をします。

    キャンセル

  • 2019/05/28 10:04

    編集後のコードとコメント見ましたが、failに入っているならphp側はcatchの方に入ってしまってますよ。
    post()とregistration()の動作をもう一度1ステップずつ確認してくのがいいと思います。

    仮に $res = $ajax_processing->post(); の部分を
    $res = [1,2,3];とでもすればそのまま処理されるのでjavascript側はdoneに入る。

    キャンセル

+1

たぶんdataType:'JSON',にしたほうがいいんじゃないかなと。
headerにもそう指定していますし、JSONで取得したいようですし。
Unexpected token < in JSON というのはJSON形式として正しくない時に出るエラーの筆頭ですし。
もちろんException 拾った時のheaderもJSONで送信したほうが良いです。

jQuery.ajax(options)

dataType / string
サーバから返されるデータの型を指定します。省略した場合は、jQueryがMIMEタイプなどを見ながら自動的に判別します。指定可能な値は、次のようなものです。
"xml": XMLドキュメント
"html": HTMLをテキストデータとして。ここにscriptタグが含まれた場合、処理は実行されます。
"script": JavaScriptコードをテキストデータとして。cacheオプションに特に指定が無ければ、キャッシュは自動的に無効になります。リモートドメインに対するリクエストの場合、POSTはGETに変換されます。
"json": JSON形式のデータとして評価し、JavaScriptのオブジェクトに変換します。
"jsonp": JSONPとしてリクエストを呼び、callbackパラメータで指定した関数に呼び戻された値をJSONデータとして処理します。(jQuery 1.2より追加)
"text": 通常の文字列。
dataTypeを指定する際は、幾つかの注すべき点があります。後述の注意1,2も参照して下さい。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/22 11:17 編集

    間違いないです。jsonで返したい以上、jsonにするべきですね。
    経緯だけ述べますと、jsonでそもそも返っていないから反映されないのではと推測し、textに変えてみました。結果としては変化なしなので、その部分は問題ないとしました。

    キャンセル

  • 2019/05/22 11:26

    >jsonで返したい以上、textにするべきですね。
    JSONで返したい以上、JSONにするべき・・の間違いでは?

    キャンセル

  • 2019/05/22 11:27

    もう少し簡単なコードで試したほうがいいですね。
    送るときはdata何も送らず、返す時はJSON形式で{result:"OK"}のみ返すとか。次に固定値送ってその固定値をそのままJSONに入れこんで返すとか。

    キャンセル

  • 2019/05/22 11:40 編集

    わかりました。試してみます。

    textの部分は変更しました。

    キャンセル

+1

どうしてnameが定義されていないのか理解できなくなり、余計混乱してくる。

POSTで送っているのに$_GET["name"]で取得しようとしているから。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/27 20:05

    こちらの回答のおかげでnameは定義されるようになりました。ありがとうございます!

    キャンセル

check解決した方法

0

やっと解決しました。みなさんご協力ありがとうございます。

自分が問題と思っていなかった部分が問題でした。PHP-Aのソース「require_once('management.php');」の前にデータベースの定義を行うphpファイルがあったのですが、phpを書く際に使う「?>」が反応してしまいうまく結果が返されなかったようです。
「<?php」のみにしてみたら解決できました。

また、PHP-Bのarrayで囲んだ部分も書き方がよくなかったので、[]に変更。結果、データベースに表示されてかつサイトに反映されるプログラミングがかけました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/04 16:30

    下記の記事の
    https://qiita.com/tadsan/items/fb496e450fc27c8c4494
    「テンプレートとロジックは分けろ」を参照してください。
    PHPタグで囲われていない部分は全て出力になるので、何も出力することがないのでしたら?>は書く必要はないです。

    キャンセル

0

「PHP Notice: Undefined index: name in (場所)」

というNoticeを吐くのであればphpのprint(もしくは参照)箇所を
tryしておきて、catchされたときはエラーヘッダを返すことです

sample

  • hoge.php
set_error_handler('myErrorHandler');
function myErrorHandler($errno, $errstr, $errfile, $errline){
  switch($errno) {
  case E_NOTICE:
    throw new exception("notice:".$errstr);
    break;
  default:
    return false;
  }
  return true;
}

try{
  print $a;
}catch(exception $e){
  header('HTTP/1.1 400 Bad Request');
  //header('HTTP/1.1 500 Internal Server Error'); //エラー番号は適当に
  print $e->getMessage(); 
}

これを以下のajax処理で参照するとよいです

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(function(){
  $.ajax({
    "url":"hoge.php",
  }).done(function(data){
    console.log(data);
  }).fail(function(xhr,err){
    console.log(err);
  });
});
</script>


hoge.phpはエラーヘッダをつけて返してくるのでfailにデータは流れます

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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