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

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

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

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

2回答

4433閲覧

CakePHP3.6 エラーメッセージがわからない

nnahito

総合スコア2004

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

2グッド

1クリップ

投稿2018/10/10 01:56

編集2018/10/10 03:25

環境など

  • CakePHP3.6
  • Docker or AWS
  • php7.2

質問したい事象

何かしらエラーが発生した際に、だいたい以下のエラーメッセージが表示されます。

Error: [Error] Call to a member function user() on boolean

しかし、エラー該当箇所は別の場所にあります。
(つまり、エラーメッセージが役に立たない)

質問詳細

CakePHP3.6(PHP7.2)を利用しています。
CakePHPで何かしらエラーが発生した際、以下のエラーメッセージがよく表示されます。

Error: [Error] Call to a member function user() on boolean Stack Trace: #0 /var/www/html/src/Controller/ErrorController.php(55): App\Controller\AppController->beforeRender(Object(Cake\Event\Event)) #1 /var/www/html/vendor/cakephp/cakephp/src/Event/EventManager.php(353): App\Controller\ErrorController->beforeRender(Object(Cake\Event\Event)) #2 /var/www/html/vendor/cakephp/cakephp/src/Event/EventManager.php(330): Cake\Event\EventManager->_callListener(Array, Object(Cake\Event\Event)) #3 /var/www/html/vendor/cakephp/cakephp/src/Event/EventDispatcherTrait.php(114): Cake\Event\EventManager->dispatch(Object(Cake\Event\Event)) #4 /var/www/html/vendor/cakephp/cakephp/src/Controller/Controller.php(777): Cake\Controller\Controller->dispatchEvent('Controller.befo...') #5 /var/www/html/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php(329): Cake\Controller\Controller->render('error500') #6 /var/www/html/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php(205): Cake\Error\ExceptionRenderer->_outputMessage('error500') #7 /var/www/html/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php(118): Cake\Error\ExceptionRenderer->render() #8 /var/www/html/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php(100): Cake\Error\Middleware\ErrorHandlerMiddleware->handleException(Object(Error), Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #9 /var/www/html/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Error\Middleware\ErrorHandlerMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #10 /var/www/html/vendor/cakephp/cakephp/src/Http/Runner.php(51): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #11 /var/www/html/vendor/cakephp/cakephp/src/Http/Server.php(98): Cake\Http\Runner->run(Object(Cake\Http\MiddlewareQueue), Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #12 /var/www/html/webroot/index.php(40): Cake\Http\Server->run() #13 {main}

しかしながら、エラーの内容はもっと別のところにあります。
例えばyum installを実行するのを忘れていた等。。。

CakePHPは、AppControllerにAuth処理を入れたらエラーメッセージが固定されてしまうのでしょうか?
それとも私のやり方が間違っているのでしょうか。

後者の場合、修正方法をご教示いただきたいです……

また、beforeFilterbeforeRenderを公開可能な部分で以下に提示させていただきます。

public function beforeFilter(Event $event) { // コントローラー名を取得 $controllerName = $this->getRequest()->getParam('controller'); // そのコントローラー内でアクセス許可するアクションリストを取得 $allowAccessMethod = $this->_getAllowAccessMethod($controllerName); if ($allowAccessMethod) { // アクセス許可アクションリストを、登録 $this->Auth->allow($allowAccessMethod); } return parent::beforeFilter($event); }

_getAllowAccessMethodメソッドは別途定義してあり、配列が返ります。

public function beforeRender(Event $event) { // ユーザのログイン情報を取得 $user = $this->Auth->user(); // ビューに渡す $this->set('user', $user); }

申し訳ありませんが、よろしくお願いいたします。

追記

Authの認証について追記させていただきます。
今回、ユーザのログインなどには、CakePHPのAuthコンポーネントのIdentifyは使っていません。
理由として、認証を外部のSaaSに委託しているため、APIを叩いてユーザの有無、ユーザ情報の正誤をSaaS側で判断し、
SuccessかFailを返してもらっているからです。
こちらではユーザの情報をほぼ持っていないので、
ログインが成功した際は、$this->Auth->setUser($user);というふうに、手動でデータをセッションに追加しています。

こちらも関係あるのでしょうか?

追記2

本文の「beforeRender」の処理の中の、

// ユーザのログイン情報を取得 $user = $this->Auth->user();

部分でAuthを使わない($user = '';)状態にすると、正常にエラーメッセージが表示されるようになりました

set0gut1👍を押しています

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

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

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

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

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

m.ts10806

2018/10/10 01:59

重箱の隅をつつくようで申し訳ないですが、質問者さんはCakePHPに関する質問を幾つかされてきていますが、それでも「はじめて」なんですか?
nnahito

2018/10/10 02:06

はい、3月に初めて触り始め、初めてだからわからない部分を幾度と質問させていただいております。実際、業務・自身でCakePHPを触るのは初めてですし、これが私のはじめてのサービスです。ところで、このご質問はご回答していただくにあたり、必要なことでしょうか。申し訳ないのですが、私はどのように質問を修正すればよいかがわからず…察しが悪く申し訳ありません。
m.ts10806

2018/10/10 02:39

ですので、あくまで「重箱の隅をつつくような指摘」です。これだけではこの質問と過去質問の関連性が分からないので。「あれ?前もCakePHPの質問してたのになんではじめて?」と疑問に思っただけです。それに問題の要件としては、はじめてかどうか関係はないと思います。環境情報の中にあるのが違和感ですね。
退会済みユーザー

退会済みユーザー

2018/10/10 02:54

loadComponent('Auth') を AppController じゃ無いところ(認証位置)でよんでそうだなw
nnahito

2018/10/10 02:55

おお!なるほど、ありがとうございます!確かに関連性はありませんでしたね。失礼いたしました。そこ、省いておきます!ご指摘ありがとうございます
m.ts10806

2018/10/10 02:58

細かいところ何度もお騒がせしました
nnahito

2018/10/10 02:59

> loadComponent('Auth') を AppController じゃ無いところ(認証位置)でよんでそうだなw  ->  今IntelliJの全文検索してみましたが、呼んでるのはAppContolloerだけでしたね……管理画面用のAppControllerも用意してあるので、その2つで呼んでますが、これはだめ…?
退会済みユーザー

退会済みユーザー

2018/10/10 03:06

事象が発生しているコントローラーでイニシャライズ関数を上書きして親クラスのをよんでないとか
nnahito

2018/10/10 03:12

「parent::initialize();」は呼んでます。この呼び出す位置は、initializeメソッドの最下部で大丈夫でしょうか?それともloadComponentとかする前に呼び出すべきでしょうか?
退会済みユーザー

退会済みユーザー

2018/10/10 03:23

基本は先頭で呼ぶ(上書き・無効化・設定変更等するため)でも呼ぶ位置では変わらない
nnahito

2018/10/10 03:25

なるほど、ありがとうございます。本文に1点追記しました。(「追記2」です)
退会済みユーザー

退会済みユーザー

2018/10/10 03:25

echo get_class($this->Auth); (だったかな)でクラス名はなにになっているか
nnahito

2018/10/10 03:29

「Cake\Controller\Component\AuthComponent 」でした!
退会済みユーザー

退会済みユーザー

2018/10/10 03:30

追記2の直前で?
nnahito

2018/10/10 04:20

はい、そうですね!   echo get_class($this->Auth); (改行) // ユーザのログイン情報を取得 (改行) $user = $this->Auth->user();  です!
guest

回答2

0

ベストアンサー

エラーメッセージを見るとエラー出力時のエラーのように見えます。

#0 /var/www/html/src/Controller/ErrorController.php(55): App\Controller\AppController->beforeRender(Object(Cake\Event\Event))

以下の2のエラーで表示が上書きされているように見えます。

  1. なんらかのエラー
  2. ErrorController によってエラー処理(ここで再度エラー)

ErrorControllerの処理やエラー時にAuthの設定がどうなるかを見てみると良いと思います。

投稿2018/10/10 09:13

編集2018/10/10 09:21
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

nnahito

2018/10/11 02:01

ご回答有り難うございます! > エラー時にAuthの設定がどうなるかを見てみる こちらなのですが、Authの設定……というのは、「$user = $this->Auth->user();」の部分という意味でしょうか?
nnahito

2018/10/11 02:03

例えばエラー時に、 var_dump($this->Auth->user()); die; のようにしても、Authのエラーが出ますね…… これは、Auth自体が使えていないことになると思うのですが、 原因の調べ方がわからず…
退会済みユーザー

退会済みユーザー

2018/10/11 04:35

`ErrorController` で `$this->Auth` が未定義だということはどこかで `loadComponent` が実行されていないことを疑うことができます。 なので `ErrorController` で `loadComponent` をしているメソッドをオーバーライドしていたりしませんか? たとえば初期だと`parent`していないので上書きされてしまいます。 https://github.com/cakephp/app/blob/master/src/Controller/ErrorController.php
nnahito

2018/10/11 08:08 編集

ご返信有難うございます。 > たとえば初期だと`parent`していないので上書きされてしまいます。 今、すべてのControllerとComponentを確認したのですが、 すべてinitializeメソッドの中に、「parent::initialize();」が書かれておりました……
退会済みユーザー

退会済みユーザー

2018/10/11 14:12 編集

ログを見る限りではErrorControllerからのエラーだと思われるのでそこを調査ですね... ErrorControllerのinitializeメソッドでparent::initialize()のすぐ下で dd($this->Auth) をしてみてセットされてるか確認してみて下さい。 セットされてなければ試しにErrorControllerでloadComponentしてみてください
nnahito

2018/10/12 04:59

ご返信有難うございます。 今確認したのですが、ErrorControllerのinitializeに「parent::initialize()」が ない のですが…… もしかしてこれ原因だったりします?
退会済みユーザー

退会済みユーザー

2018/10/12 06:23

そうですね。 ErrorController::beforeRender() までにAuthコンポネーントをloadComponentしてないからエラーになっていると思いますので。
退会済みユーザー

退会済みユーザー

2018/10/12 06:25

スタックトレースの読み方がわからないほうだったのか(ぉ
nnahito

2018/10/12 10:28

あー……なんてことだ……ありがとうございます! きれいにエラーが表示されました! なんでここの「parent::initialize()」が消えていたのだろう……
退会済みユーザー

退会済みユーザー

2018/10/12 11:56

良かったです! cakeのプロジェクト作った初期状態だとErrorControllerにはparent::initialize()がない状態だからですかねー 何もしてなければ無いままです
退会済みユーザー

退会済みユーザー

2018/10/12 12:00

エラーハンドリング用のコントローラーはDB処理(loadModel)を省く必要があるため 親クラスをロードシてはいけませんよ
guest

0

エラーメッセージが固定されるわけではなく、Auth 処理に問題があるからエラーが出ているのです。
※Auth 処理はどの画面でも、画面の処理に先立ち呼び出されますから、そこでエラーが出れば「常に同じ場所でエラーが起きている」ことになります

この例でいうと、おそらく $this->Auth が正しくないので、$this->Auth->user() が呼び出せなくなっています。

投稿2018/10/10 02:01

tacsheaven

総合スコア13703

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

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

nnahito

2018/10/10 02:22

ご回答有り難うございます。 > $this->Auth が正しくないので、$this->Auth->user() が呼び出せなくなっています。 なるほど…… 通常呼び出せますが、なにかのきっかけで呼び出せなくなっている…という認識で大丈夫でしょうか? となると「beforeRender」の処理がなにかおかしい感じでしょうか?
tacsheaven

2018/10/10 02:26

beforeRecder ではなく、$this->Auth を設定しているところで何かしくじっていると思います。
nnahito

2018/10/10 02:31

ご返信有難うございます。 思い当たる点が一つあり、本文に追記させていただきました。 認証処理をSaaSに委託しておりこちら側ではユーザ情報を持っておらず、AuthのIdentifyメソッドを使っていません。(setUserを使っている) もしかしてこの場合、なにか必要な処理があったりするのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問