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

シェアする

  • このエントリーをはてなブックマークに追加

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

 

スポンサードリンク

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

 

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

laravel-logo
Laravelでソーシャルログインを実装してみました。Socialiteをインストールするまず、Laravelにソーシャル認証用のプラグインSocialiteを...

 

 

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

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

 

 

早速実験してみます。

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

sns
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_Logo-320x320
PHPを学習していて基本的な文法をマスターした後にデータベース連携やユーザー認証、CRUD処理などをするのに適した本を探していて次の本を見つけました。この種はW...

 

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

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

 

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です