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

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

新規登録して質問してみよう
ただいま回答率
85.35%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

981閲覧

POST http://example.php 500 (Internal Server Error)のエラーの拾い方

pegy

総合スコア245

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2021/08/04 06:58

編集2021/08/04 06:59

現在、クライアント側で下記の様なコードで以下の様にしてurl先のajax.phpでMYSQLの処理をしています。
そこで意図的にSQL文においてSyntax Errorを出すと.fai()lで拾ってくれる わけではなく、ブラウザ上console上にPOST http://example.php 500 (Internal Server Error)の様な形でエラーが出力されます。
サーバー側でこの様なエラーが起きていることをJSやphp側で拾いたいのですが、可能なのでしょうか?

無理やりサーバー側のajax.phpini_set('display_errors', 1)を入れてエラーを出力させて、この結果をdone()で受け取る様な方法はあるのですが、Syntax Error 等ではない軽微なものも拾ってしまうこともありますし、そもそも適切なやり方ではないと推察してご照会させていただきました。

よろしくお願い申し上げます。

javascript

1 $.ajax({ 2 url:url, 3 method:"POST", 4 data:{ 5 'user_id':user_id, 6 'text':text, 7 } 8 }) 9 .done((get_data)=>{ 10 if(!Array.isArray(get_data)){ 11                         //do something 12 }else{ 13 //do something 14 } 15 }) 16 .fail((jqXHR,)=>{ 17 $('<div class=""><span class="color_alert">ERRCODE-900</span>:通信エラーです、通信環境を確認してください</div>').appendTo('.function_error_box').hide().fadeIn(1000); 18 })

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

回答

JavaScriptに渡される=エンドユーザーが見ようと思ったら見れちゃうわけなので、
開発に必要な詳細情報(例えばSQLのシンタックスエラーが出ています!みたいなエラーメッセージ)を表示するのが正しいかと言うとそうでは無く、
まだ現状のデフォルトのエラーメッセージが出ている(質問内容からはそのように見える)方がマシだと言えます。

エラーやNotice,Warningはサーバ側でログに記録しておいて、開発する時はサーバ側でtail -f しながら開発するのが良いかと思いますよ。

発生している問題(予想)と解決方法

SQLエラーがPHPでどうハンドリングされているか次第ですが、500が出てるという事は例外は発生していると事だと思います。

多分こんな感じ

PHP

1 //prepareとか色々あって 2 $prepare = $dbh->prepare('SELECT name FROM fruit WHERE price = ?'); 3 $prepare->bindValue(1,(int)$price,PDO::PARAM_INT); 4 $prepare->execute(); 5 $result = $prepare->fetch(); 6 //resultの結果によってJSONを構築してる? 7 echo jeson_encode($result); 8

この場合、SQLエラーがあった場合、Uncaught Exceptionが発生して500エラーが出力されます。
問題の本質は、例外を適切にハンドリング出来ていない事です。
そのため、例えば以下の様な形で例外をキャッチしてから、50xレスポンスヘッダを出力しつつ、エラーメッセージを出力することでJavaScript側で問題を取得できます。

PHP

1 try{ 2 //prepareとか色々あって 3 $prepare = $dbh->prepare('SELECT name FROM fruit WHERE price = ?'); 4 $prepare->bindValue(1,(int)$price,PDO::PARAM_INT); 5 $prepare->execute(); 6 $result = $prepare->fetch(); 7 //resultの結果によってJSONを構築してる? 8 echo json_encode($result); 9 //実際には例外の種類で先にハンドリングする 10 }catch (Exception $e){ 11 header('HTTP/1.1 500 Internal Server Error');//500なり503なり404なり状況に合わせて出力 12 $err = [];//JavaScriptに見せたい範囲でエラーを記述したり、例外から判定して生成する 13 echo json_encode(); 14 }

ただ、前述の通り、SQLシンタックスエラーを出したりするのは攻撃者に不要なヒントを与えることになるので少なくとも本番環境では表示するべきでは無いと思います。

投稿2021/08/04 07:33

編集2021/08/04 07:37
tanat

総合スコア18727

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2021/08/04 08:13

ありがとうございます。75%くらい理解することができました。 当初の質問においてもSyntax Errorそのものを出力するというよりも、その類のものが出ている場合ユーザーに分からない様に管理者エラーの様に捌くことができればと考えておりました。そういう点ではまさに、MYSQLの例外をcatchして header('HTTP/1.1 500 Internal Server Error')から識別してサーバー側で判断して内容はユーザーに見せないで対応するというのは理解できました。 ただ、ご意図が汲みとれかった点として、以下の2点がございます。 1. header('HTTP/1.1 500 Internal Server Error');//500なり503なり404なり状況に合わせて出力 の点において、サーバー側でどの種類のエラーなのかということをPHP側で判断することができるのでしょうか?今のところ500しか見たことがないのですが、他のエラーが発生した時にどの様に識別すれば良いのか?それともそもそもすべてのエラーパターンを記述して分岐させるのが正しいのか分からずにお尋ねさせてください。 2.catchの中において $err = [];//JavaScriptに見せたい範囲でエラーを記述したり、例外から判定して生成する echo json_encode(); というのはecho json_encode($err[$0]);の様にクライアント側に分からない様に出力することが考えられれますということでしょうか?ご提示のコードでは何をjson_encode()か分からずに念のためにお尋ねさせてください。 ""エラーやNotice,Warningはサーバ側でログに記録しておいて、開発する時はサーバ側でtail -f しながら開発するのが良いかと思いますよ。 これに関しては、サーバー側でどうやってエラーログを取るのかや、tail -fというコマンドを、正直初心者で全く存じ上げておらず、これから時間をかけて調べます!
tanat

2021/08/04 08:48

> その類のものが出ている場合ユーザーに分からない様に管理者エラーの様に捌くことができればと考えておりました という事であれば、JavaScritpに渡した時点でユーザーにも分かるようになってしまうので、ログで確認するしか無いかと思いますよ。 > 1. header('HTTP/1.1 500 Internal Server Error');//500なり503なり404なり状況に合わせて出力 の点において、サーバー側でどの種類のエラーなのかということをPHP側で判断することができるのでしょうか? どこまでハンドリングするか次第ですが、例外がthrowされているのであれば、catchした後は自由に判断することが出来ます。 FatalエラーやParseエラーまでハンドリングしたいのであれば php fatal error ハンドリング あたりで調べてみて下さい。 > 2.catchの中において > $err = [];//JavaScriptに見せたい範囲でエラーを記述したり、例外から判定して生成する > echo json_encode(); echo json_encode();は記載ミスでecho json_encode($err);ですね。(修正しておきます) > というのはecho json_encode($err[$0]);の様にクライアント側に分から> ない様に出力することが考えられれますということでしょうか? 違います。 echo したものは全てJavaScript側=エンドユーザーから読めてしまうので、読まれても問題無い状態まで加工して出す必要があります。 良くあるのは、内部的には判別できる形のエラーのリストを作っておいて、ブラウザにはエラーコードだけを表示させて、「このエラーコードで問い合わせて下さい」みたいなケースですね。
tanat

2021/08/04 08:49

> これに関しては、サーバー側でどうやってエラーログを取るのかや、tail -fというコマンドを、正直初心者で全く存じ上げておらず、これから時間をかけて調べます! この辺は、環境によっても変わってきますが php エラーログ 出力 確認 あたりのキーワードに使用しているOSやwebサーバー名(Apacheとかnginxとか)を加えて検索してみると必要な情報が見つかるかと思います。
pegy

2021/08/05 07:16

ありがとうございます。実はコメント頂いていてから色々試してみてからご返信しようと思い丸1日経過してしまいました。。申し訳ございません。 現在もミニマムコードで例えばSELECTをSELECTSなどにしてわざとSYNTAX ERRORを発生させた場合どうやってcatchできるのかと奮闘中です。また、諸々コードを動かしてからコメントさせていただきます。。 初心者で時間がかかってしまい、お詫び申し上げます。
tanat

2021/08/05 07:39

ミニマムという意味では、まずはDB接続をせずに単にエラーを発生させて動作を確認してみるのがお勧めです。 例えば ajax.php で throw new Exception("テスト例外"); とだけした場合と try{ throw new Exception("テスト例外"); }catch(Exception $e){ echo $e->getMessage(); } とした場合 try{ throw new Exception("テスト例外"); }catch(Exception $e){ header('HTTP/1.1 500 Internal Server Error');//500なり503なり404なり状況に合わせて出力 echo "エンドユーザーには見せたくない原因で問題が発生しました" } とした場合で、 アクセスログ エラーログ ブラウザ側に表示されるメッセージ ブラウザ側で取得できるレスポンスコード 辺りを比較すると、イメージが掴みやすいかもしれません。
pegy

2021/08/05 08:12

ありがとうございます。 throwとそれをcatchする構造は理解ができる様になりました。 まさに "SQLシンタックスエラーで例外を投げてくれない という部分で躓いているため参考記事を熟読してみます。
pegy

2021/08/06 02:01

tanat様 本当に申し訳ございません、1日勉強しても答えに到達できませんでした。。またtry-catchの使い方やブラウザでのレスポンスコードやheaderの確認の方法についても十分理解できていない部分がありここらへんはミニマムの例示をもとに改めて勉強をさせていただきました。アクセスログ、エラーログについてはサーバーサイド(php)側の話なのかと理解してのですが。。。間違っていたら申し訳ございません。 さて、今回当初のご指摘に戻るとエラーハンドリングの問題であるということであったと思います。そこで、仮に入力値や何かの拍子にajax.php側で500 Internal Server Error等が出てしまった場合、原因はユーザーには見せないが何かしらこの原因を特定して必要な情報を出力する必要があると考えておりました。 そこで、頂いたヒントを元に、 try{  if (/*syntax error*/) { throw new Syntax_Exception("例外1"); } elseif(/*fatal error*/) { throw new fatal_Exception("例外2"); }else{ // 通常どりの処理を実行 }   }catch(Syntax_Exception $e){ header('HTTP/1.1 500 Internal Server Error');  echo "例外1"です }catch(Fatal_Exception $e){ header('HTTP/1.1 500 Internal Server Error');  echo "例外2"です } の様な形でハンドリングしなくてはいけないと解釈しておりました。またこの様にする理由の一つが、デフォルトでのPDOExceptionクラスがSyntaxエラーを投げてはくれないからという様に理解しておりました。 そして、やはりこのtryの中のエラーハンドリングの方法がわからず行き詰まってしまいました。そもそも、ご助言いただいたにもかかわらず、やはりアプローチそのものが間違っていたら申し訳ざいません。ご指摘をいただければ幸いです、
tanat

2021/08/06 04:06

> の様な形でハンドリングしなくてはいけないと解釈しておりました。 混乱させてしまったら申し訳ありません。 ミニマムコードとして出したものは、自分でエラーを発見して例外をthrowする例です。 try-catchそのものの動作の把握のみを意図しての例示でした。 PDOの場合、(適切に設定を行えば[https://qiita.com/mpyw/items/b00b72c5c95aac573b71])SQLシンタックスエラーに関しては自動で例外(PDOException https://www.php.net/manual/ja/class.pdoexception.php)をthrowしてくれるので、catch内だけ考えれば問題ありません。
pegy

2021/08/06 05:08

ありがとうございます、こちらこそ適切な質問ができず混乱させてしまって申し訳ございませんでした。catch内での処理について、シンタックスエラーの拾い方や分岐を検討したいと思います。
guest

0

試したわけではないですが、以下はどうですか?

js

1.done((get_data, textStatus, jqXHR)=>{ 2 console.log(jqXHR.status)

The jqXHR Object | jQuery.ajax() | jQuery API Documentation

投稿2021/08/04 07:10

Lhankor_Mhy

総合スコア36960

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2021/08/04 08:02

コメント、ありがとうございます。 仮に "SELECT * FFROM dummy"の様にして結果を試しましたが、500 (Internal Server Error)のエラーがブラウザコンソールに出力されるだけでした。
Lhankor_Mhy

2021/08/04 08:14

500のエラーコードを出したい、というご質問かと思ったのですが、違ったのですね。 失礼しました。
pegy

2021/08/06 02:08

いえ、とんでもございません。コメントをお寄せいただき誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問