PHPでnamespace内でExceptionをcatchするときは、エスケープシーケンス(バックスラッシュ)\が必要

LaravelのPHPで、かなりハマってしまった問題。

スポンサーリンク

Laravelでソーシャルログインの認証拒否のテスト

Laravelでソーシャル認証を実装しました。

Laravelでソーシャル認証(Twitter, Facebook, Google)を実装してみた
Laravelでソーシャルログインを実装してみました。 Socialiteをインストールする まず、Larave...

LaravelのControllerでコールバック内では、以下の通りに実装しました。

これで、Exceptionが発生してもcatchしてリダイレクトされるはずです。

早速実験してみます。

ソーシャルログイン時に以下の記事出てくる画面が表示された場合、Twitter、Facebook、Googleでログインを拒否したとします。

Twitter, Facebook, Googleでアプリケーションの連携を解除する
Twitter, Facebook, Googleといったユーザーのアカウントを使って、他のWEBサイトにログインする、いわゆるソーシャルロ...

すると、それぞれ次のエラーが発生します。

Twitterで拒否した場合

https://(url)/auth/login/callback/twitter?denied=xxxxx

InvalidArgumentException in TwitterProvider.php line 15:Invalid request. Missing OAuth verifier.

Facebookで拒否した場合

https://(url)/auth/login/callback/facebook?error=access_denied&error_code=200&error_description=Permissions+error

ClientException in RequestException.php line 107:Client error: GET https://graph.facebook.com/oauth/access_token?client_id=ccc&client_secret=ddd&redirect_uri=(url) resulted in a 400 Bad Request response:
{"error":{"message":"Missing authorization code","type":"OAuthException","code":1,"fbtrace_id":"xxx"}}

Googleで拒否した場合

https://(url)/auth/login/callback/google?error=access_denied&state=

ClientException in RequestException.php line 107:Client error: POST https://accounts.google.com/o/oauth2/token resulted in a 400 Bad Request response:
{
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}

これ、全部、以下の関数の呼び出し元でExceptionが発生しています。

$user = Socialite::driver('twitter')->user();

ちゃんとTry~CatchでExceptionをCatchしているのに何で????

PHPでネームスペース内で例外をキャッチするときは、グローバルスペースにエスケープしないとダメ

調べてみるとちゃんと書いてありました。

When catching an exception inside a namespace it is important that you escape to the global space:

私の不勉強で、PHPの仕様としては初歩的な考え方で、ミスっていました。

以下のようにしてしまうと、Exceptionでcatch出来るのは、同じネームスペース内のExceptionのみになってしまいます。

Socialite::driver内でのExceptionはcatch出来ません。

Socialite::driver内のExceptionをcatchするには、以下のように、Exception ではなくて、バックスラッシュを付けてグローバルな名前空間であることを示して、\Exception をcatchする必要があります。

これでOKです。

まとめ

Exceptionのグローバルなnamespaceの考え方は、C#にもJavaにも存在しない概念のはずです。

私のようにJava、C#出身のPHPプログラマーは勘違いしてしまいます。

PHPの文法は以下の本で勉強し直します。

PHPとデータベース連携を学べる中級以上向けの本、おすすめ
PHPを学習していて基本的な文法をマスターした後にデータベース連携やユーザー認証、CRUD処理などをするのに適した本を探していて次の本を見つ...

どれか一冊という人には以下の「PHP+MySQLマスターブック」をおすすめします。

最後まで読んでいただきありがとうござました。
この記事が気に入っていただけたらシェアしてくれると嬉しいです。

スポンサーリンク
スポンサーリンク
Translate »