質問: args[1] + '(HTTP request failed)'; } return error; } // DOMを全て読み込んだあとに実行される $(function () { // 「#execute」をクリックしたとき $('#execute').click(function () { // Ajax通信を開始する $.ajax({ url: 'api.php', type: 'post', // getかpostを指定(デフォルトは前者) dataType: 'json', // 「json」を指定するとresponseがJSONとしてパースされたオブジェクトになる data: { // 送信データを指定(getの場合は自動的にurlの後ろにクエリとして付加される) age: $('#age').val(), job: $('#job').val(), }, }) // ・ステータスコードは正常で、dataTypeで定義したようにパース出来たとき .done(function (response) { $('#result').val('成功'); $('#detail').val(response.data); }) // ・サーバからステータスコード400以上が返ってきたとき // ・ステータスコードは正常だが、dataTypeで定義したようにパース出来なかったとき // ・通信に失敗したとき .fail(function () { // jqXHR, textStatus, errorThrown と書くのは長いので、argumentsでまとめて渡す // (PHPのfunc_get_args関数の返り値のようなもの) $('#result').val('失敗'); $('#detail').val(errorHandler(arguments)); }); }); }); ``` お聞きしたい点は2点です。 ajax通信が成功した際に処理される、「done」メソッド内の「$('#detail').val(response.data);」ここの「data」は、「api.php」の「echo json_encode(compact('data'));」ここの配列「data」のことを指しているのでしょうか? もう一点目は、失敗した場合のfailメソッド内の「 $('#detail').val(errorHandler(arguments));」ここの「arguments」です。errorHandler関数の中身から、配列かとは思うのですが、ajax通信行われた際に用意される特殊なものなのでしょうか? どなたか、教えて頂けましたら幸いです。 よろしくお願いします。
回答: 質問に直接関係ある部分ではないですが、気になった点。 ``` $age = (string)filter_input(INPUT_POST, 'age'); $job = (string)filter_input(INPUT_POST, 'job'); ``` 安易なキャストは潜在的なバグを増やすだけになるのでやめたほうが良いです。 それにせっかく filter_input()を使っているのですから機能をきちんと使いましょう。 フラグ次第ですが、デフォルトではキーが存在しなかったらnull、filterに失敗したらfalseが返ってきます。 型が気になるなら検証フィルタかけてチェックすればそもそもageにかけてるctype_digit()のチェックも不要になります。 それに、もしage,jobが配列で送信されたらどうなると思いますか? チェックボックスでなくてもnameに[]で設定すれば配列で送信されます。 そうなるとキャストでstringにしてしまってはバグに気づけなくなります。 ajaxとのことで実行されるプログラムは独立したアプリケーションとして動作しているものなので、 「必ずあるところから呼び出される前提」「くる情報の形が決まっている」「強制変換」は不具合を潜在化し、問題の切り分けを困難にします。 (くる情報が決まってるならなおさらキャストの必要はないですけど) ``` } else if (($age = (int)$age) > 100) { ``` ここもそうですね。ただ、ここは`=`になっている意味が分かりませんが。 ``` if (!isset($error)) { ``` バリデーションの結果が必ず1つしか引っかからないというあまりよくない前提が含まれています。 「job」がどういう風にデータが送られるのかわかりませんが、例えば「セレクトボックスなど選択肢から選ばれる」という場合、「選択肢にないものが選ばれたらNG」とする必要が出てきます。 となると「ageが数字でない」と「選択肢にないものが選ばれる」は同時に起きうる現象になりますよね。 そのあたりも想定するのでしたら$errorは配列にしておくべきと思います。 ``` $error = []; /* バリデーション */ if(count($error) === 0){ //バリデーションOK }else{ //バリデーションNG } ``` ``` $data = "{$age}歳、{$job}です"; echo json_encode(compact('data')); ``` 入力値が正常でそのまま返しているだけならわざわざPHPで文字列作る必要ないのでは。 ajaxのdoneで受け取れる引数の `jqXHR.done(function( data, textStatus, jqXHR ) {});` textStatusで判断しても良いと思います。 ``` "success" "notmodified" "error" "timeout" "abort" "parsererror" ``` 「返すのがJSON」というのが決まっていてとりあえずOKだったと返したいなら配列を直接突っ込んでjson_encode()すれば良い話ですし。 ``` echo json_encode(['result'=>'0']); ``` ``` http_response_code(400); echo json_encode(compact('error')); ``` 1つ前にあわせてこんな感じで。 ``` echo json_encode(['result'=>'9','error'=>$error]); ``` ここでcompact()って微妙な感じはするので私はより明示的に連想配列を作って返すことが多いです。 まあここは好みで(あと現場のルールがあればそれに従う、と)