シェアする

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

[CakePHP2]ビュー(View)以外でヘルパー(Helper)を使う方法

CakePHP1.3では、ビュー以外の場所でヘルパーを使う場合に以下のようにすれば使うことができました。

hogesController

App::import('Helper', 'Html');
$this->Html = new HtmlHelper();

$linkText = $this->Html->link("topページ", "/");

ところがCakePHP2系では、この記述ではHelperを利用することができません。
正解はこう。

	App::uses('HtmlHelper', 'View/Helper');
	$this->Html = new HtmlHelper(new View());
	
	$linkText = $this->Html->link("topページ", "/");

この正解にたどり着くまでに色々失敗をしたので、その失敗の過程をお見せしつつ解説します。

失敗1

とりあえず前述のように1.3系と同じ書き方をして失敗。

Warning (4096): Argument 1 passed to HtmlHelper::__construct() must be an instance of View, none given, called in D:\htdocs\app\Controller\HogessController.php on line 17 and defined [CORE\Cake\View\Helper\HtmlHelper.php, line 157]
Warning (2): Missing argument 1 for HtmlHelper::__construct(), called in D:\htdocs\app\Controller\DashboardsController.php on line 17 and defined [CORE\Cake\View\Helper\HtmlHelper.php, line 157]
Notice (8): Undefined variable: View [CORE\Cake\View\Helper\HtmlHelper.php, line 158]
Warning (4096): Argument 1 passed to Helper::__construct() must be an instance of View, null given, called in D:\htdocs\lib\Cake\View\Helper\HtmlHelper.php on line 158 and defined [CORE\Cake\View\Helper.php, line 163]
Notice (8): Trying to get property of non-object [CORE\Cake\View\Helper.php, line 165]
Notice (8): Trying to get property of non-object [CORE\Cake\View\Helper\HtmlHelper.php, line 159]

Htmlヘルパー自体はincludeできてるみたいだけど、コンストラクタの第1引数の指定が無いと怒られてるっぽい。引数を調べてみるとViewのインスタンスを渡さなきゃならないみたい。どうすればいいの?

ここで色々調べたところ、App::usesの存在を知りました。
そういえばCakePHP2系からコントローラやモデルの冒頭にApp::usesの記述が追加されていました。

検索してみるとCakephperさんの記事がヒット。
1.3ではApp::importは指定したクラスが必要とするクラスも再帰的に探査してくれましたが、それがパフォーマンスに悪影響なため2系では再帰的に探査しないようになったそうです。
また2系でクラスを読み込むときには、App:usesを使うようになったとのことでした。

参考:CakePHP2.0のネーミングルールの記事翻訳 – cakephperの日記(CakePHP, MongoDB)

ここで勘違いしました。Viewもusesしないといけないということと、usesすればHtmlHelperの引数にインスタンスが渡されるのだと。考えればそんなわけないんですけどね・・・。

失敗2

じゃあApp::importをusesに変更してViewもusesしたらどうだろう?と思ってやってみたのがこれ。

	App::uses('HtmlHelper', 'Helper');
	App::uses('View', 'View');
	$this->Html = new HtmlHelper();

そしたら、次のようなエラーが出ました。

Fatal error: Class 'HtmlHelper' not found in D:\htdocs\app\Controller\HogesController.php on line 18

Htmlヘルパーの読み込みにすら失敗している様子・・・。
このあとusesの第2引数にはView/Helperのように指定することがわかったので、

	App::uses('HtmlHelper', 'View/Helper');
	App::uses('View', 'View');
	$this->Html = new HtmlHelper();

のようにしてみたら、失敗1のエラーが出ました。どうやらヘルパーの読み込みには成功したようです。でも結局振り出しに戻っただけ。。。ん?HtmlHelperの引数が足りないんだよな・・・。

正解

Argument 1 passed to HtmlHelper::__construct() must be an instance of View

というのはつまり「HtmlHelperのコンストラクタの第1引数にはViewのインスタンスが必要だ」と言われているので、じゃあ渡したるわいというわけで、次のようにしたらうまくいきました。

	App::uses('HtmlHelper', 'View/Helper');
	App::uses('View', 'View');
	$this->Html = new HtmlHelper(new View());

Htmlヘルパーのインスタンスを作るときにViewを渡してやればよかったんですね。
ちなみに、失敗2の際に勘違いしてApp::uses(‘View’, ‘View’);を追加しましたが呼びださなくても大丈夫でした。

	App::uses('HtmlHelper', 'View/Helper');
	$this->Html = new HtmlHelper(new View());

App::importもまだ使えるので次のように書いても良かったんですね。

	App::import('Helper', 'Html');
	$this->Html = new HtmlHelper(new View());

実は単純にHelperのインスタンスを作るときにViewを渡すようになっただけでした。
遠回りしちゃいましたねσ(^_^; )

シェアする

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

フォローする