■ユーザーズフォーラム リニューアルのお知らせ
新規投稿は新ユーザーズフォーラムにお願いします。

cron実行によるエラーについて

k_okamoto2 > cron実行によるエラーについて @ 2014/11/7 18:22
cron実行によるエラーについて何か分かる方いましたら、教えて頂きたく投稿されて頂きました。

http://wataame.sumomo.ne.jp/archives/5311
上記URLを参考にシェルを作成(下記内容)し、cron実行したのですが、
==========================================================================
class SendMailmagazineShell extends BcAppShell {

function startup() {
parent::startup();

// コントローラー設定
$this->SendMailmagazineController = new SendMailmagazineController();
}

public function sendMailmagazine() {
$this->SendMailmagazineController->sendMailmagazine();
}
}
==========================================================================

このSendMailmagazineControllerの実行において、下記エラーが出ます。
===============================================================
Error: Class 'Controller' not found
File: ******/lib/Baser/Controller/BcAppController.php
Line: 29
===============================================================

このSendMailmagazineControllerはAppControllerを継承し、
そのAppControllerはBcAppControllerを継承していますので、
そのBcAppControllerでcakeのController.phpが読み込まれていないようです。

BcAppControllerは間違っていないという前提でいろいろ試したのですが、
ちょっとわからない状態です。
BcAppControllerに別途、cakeのController.phpを読み込む処理が必要なのでしょうか?
n1215 > Re: cron実行によるエラーについて @ 2014/11/8 2:19
k_okamoto2 様

baserCMS(CakePHP2)のコンソールからの起動処理が通常のHTTPリクエストを受けた際のWebアプリとしての起動処理と異なり、
かつbaserCMS側がコンソールからの実行を考慮しきれていないのが原因のようです。

●1.Webアプリとしての起動
Webアプリの起動処理においては、DispatcherクラスがHTTPリクエストの内容(URLなど)に応じたコントローラのアクションを実行することになっています。
当然Controllerクラスを利用しなければいけないので、Dispatcherクラスに
App::uses('Controller', 'Controller');

という記述があり、Controllerクラスが読み込まれています。
https://github.com/baserproject/basercms/blob/8252033261919e17b8a8b3bcc56b8e854946c51b/lib/Cake/Routing/Dispatcher.php

つまりBcAppControllerのファイル自体には明示的にControllerクラスを利用するという記述がなくても
既に読込済なので問題ないわけです。


●2,コンソールからの起動
対してコンソールからの起動時は必ずしもコントローラを呼び出す必要はありません。
むしろShellクラスがコントローラとしての役割を担えば済むのでわざわざコントローラの処理を呼び出すのは冗長です。
実際、Webアプリ実行時のDispatcherクラスに対応するコンソール実行時のクラスShellDispatcherクラスには
App::uses('Controller', 'Controller');

という記述がありません。

そしてBcAppControllerクラスのファイルにもControllerクラスの在処は示されていないので見つからないと。
からくりはこんな感じかと。


●解決策
暫定的な対応策としては開発中のShellクラスのファイルに
App::uses('Controller', 'Controller');
を書いてしまうのが手っ取り早いでしょうね。

本来はコアのBcAppControllerのファイルにControllerクラスの利用を明示的に記述してある状態が理想なのでチケットを切りました。
http://project.e-catchup.jp/issues/7294


●余談
また、baserCMSや参考記事のメール送信がコントローラのメソッドとして実装されているのも事をややこしくしている1つの原因かもしれません。
モデル・ドメイン領域にメール送信のロジックに責任を持つクラスが存在し、シェルからもコントローラからも同じように呼び出して使うほうがスッキリしますしテストも楽です。
ShellクラスもController同様にusesプロパティでモデルを指定して読み込めるようになっています。
http://book.cakephp.org/2.0/ja/console-and-shells.html#id3
どうもCake2を使ったアプリはコントローラを太らせてしまう傾向が強いようですね。
こちらもそのうち整理してリファクタリングしたいと思います。


●補足:bootstrap処理の違い
他にもWebアプリとしての実行時と大きく異なる点があるので、コンソールのシェルの開発をする際には注意が必要です。

Webアプリとしての起動時には
・app/Config/bootstrap.php
・lib/Baser/Config/bootsrap.php
・lib/Cake/bootstrap.php
の3ファイルが読み込まれます。
特にbaserCMS特有のクラスとパスの設定がlib/Baser/Config/bootstrap.phpで行われています。
https://github.com/baserproject/basercms/blob/dev-3/lib/Baser/Config/bootstrap.php

ところがコンソールからシェルを実行した場合は、Cakeのbootstrapしか読み込まれません。
(CakePHP2がなぜこのような整合性の取りにくい仕様になってるのかが不思議でなりませんが……)
Webアプリ実行時とは各クラスの探索パスが変わったり設定が異なったりすることもあります

Twitter: @n_1215

k_okamoto2 > Re: cron実行によるエラーについて @ 2014/11/10 10:16
n1215 様

ご丁寧に説明頂きまして、誠にありがとうございます。

>暫定的な対応策としては開発中のShellクラスのファイルに
>App::uses('Controller', 'Controller');
>を書いてしまうのが手っ取り早いでしょうね。
承知致しました。
やはり別途読み込む処理が必要なんですね。
ひとまずこれにて対応しようと思います。

ありがとうございました!
n1215 > Re: cron実行によるエラーについて @ 2014/11/10 19:46
修正がマージされましたので次のバージョンでは直ります。
https://github.com/baserproject/basercms/commit/acb46157a38cf0a767fd0ba435c982bb7e3d5395

Twitter: @n_1215

ログイン
ユーザー名:
パスワード:


  新規登録 / パスワード紛失

検索

facebook
フォーラムで悩みが解決した場合など、よかったら「いいね!」をポチっとクリックしてください!質問の回答者や開発者の励みになります

フォーラムガイド


関連リンク

オンライン状況
13 人のユーザが現在オンラインです。 (12 人のユーザが フォーラム を参照しています。)

登録ユーザ: 0
ゲスト: 13