CakePHP3で、自前のヘルパーを実装しようとしたところ、思わぬところで引っかかってしまいました。
失敗へ向かう流れ
まず、このあたりを見て、だいたいどこへどんなふうに設置すればいいかを把握しました。ただ、コンストラクタに独自処理を差し込みたいと思ったので、コンストラクタのシグネチャを確認した上で、以下のように書きました。
src/View/Helper/HogeHelper.php
<?php
namespace App\View\Helper;
use Cake\View\Helper;
class HogeHelper extends Helper
{
public function __construct(View $View, array $config = []) {
parent::__construct($View, $config);
// これ以降に独自処理を差し込む
}
}
このようにしたところ、ヘルパーを読み込んだ瞬間に落ちてしまいました。
何がまずかったのか
エラーログを調べてみれば原因は明らかで、use Cake\View\View;
を忘れていたために、__construct
の引数に付けたタイプヒントのView
がApp\View\Helper\View
と認識されてしまっていました。この「どこかで定義されていると信じているApp\View\Helper\View
クラスのインスタンス」を要求するコンストラクタとなってしまい、Cake\View\View
が渡されたことでタイプヒント違反となってTypeError
となってしまったのでした。
Ruby的に書くには?
Rubyでは、super
とだけ書けば元のコンストラクタへ与えられた引数がそのまま渡りますが、PHPで「とりあえず、引数をそっくりそのまま親クラスに渡したい」という場合、以下のように書けます。
class Child extends Parent
{
public function __construct(...$args) {
parent::__construct(...$args);
}
}
ただ、PHPの場合、シグネチャを拾って情報表示するツールもあるので、今回の例のようにフレームワーク内部でnew
されるクラス以外では、あまり積極的に使わないほうがいいかな、という気もしました(関連?)。