忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/12/14 19:21 |
PHP5.4.7 トレイトその2
前回の続き。
interfaceのinstanceofで引数判定、なんてよくやることですが、instanceof演算子はtraitには反応しません
<?php
	// 基底クラス
	class A{}
	
	// trait
	trait B{
		public function hoge(){
			print('B::hoge/'.__CLASS__.'/'.__METHOD__);
		}
	}
	trait C{
		public function hoge(){
			print('C::hoge/'.__CLASS__.'/'.__METHOD__);
		}
	}
	
	// Aを継承したクラス
	class D extends A{
		// トレイトB,Cを使用
		use B, C{
			// B::hogeを優先
			B::hoge insteadof C;
			// B::hogeをfoo()に改名
			B::hoge as foo;
			// C::hogeをbar()に改名
			C::hoge as bar;
		}
	}
	$d = new D();
	
	$d->foo(); // B:hoge/D/B::hoge
	$d->bar(); // C:hoge/D/C::hoge
	$d->hoge(); // B:hoge/D/B::hoge 元のメソッド名でも反応する
	
	$d instanceof A; // true
	$d instanceof C; // false

http://tanakahisateru.hatenablog.jp/entry/20110704/1309781929
> そりゃまあ当然で、PHP5.4のトレイトは、使用者側でアドホックにメソッド名の置き換えすらできてしまうので、「必ず特定のメソッドに応答することを保証する」インターフェースとしては使えないです。

実は元のメソッド名でも反応します。
asは単にエイリアスを作るだけなので、元のメソッド自体は残っているのです。

参考リンク先にも普通に
> Test class will now have "hello" and "helloA" methods
って書かれています。

従ってトレイトを「必ず特定のメソッドに応答することを保証する」インターフェースとして使用することは可能……と思いきや実はできません。
B::hoge as private;ってするとCall to private methodになっちゃうんですよね。
なんてこった。

ということで先方のサイトはこう読み直すのがよいでしょう。

> そりゃまあ当然で、PHP5.4のトレイトは、使用者側でアドホックに可視性の変更すらできてしまうので、「必ず特定のメソッドに応答することを保証する」インターフェースとしては使えないです。

まあ、せっかくなのでtraitをインターフェースとして使ってみます。
<?php
	/**
	* @param Object インスタンス
	* @param String トレイト名
	* @return boolean instanceof
	*/
	function trait_instanceof($trait, $className){
		$class = new ReflectionClass($trait);
		$traits = $class->getTraitNames();
		return in_array($className, $traits, true);
	}
	
	$is = trait_instanceof($d, 'B');
微妙だ。
特にトレイト名を文字列で与えているあたりが微妙だ。
トレイト名はクラス名のようには扱うことができず、use節以外で使用するとUse of undefined constantのNoticeになってしまうようです。

こんな面倒なことをせず素直にmethod_exists($d, 'hoge')でいいや、と思ったのは秘密。
PHPにはこういう横紙破りな関数が揃ってるのが良くも悪くもナイスですね。

PR


2013/06/24 23:17 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<GeNERACE labo「あなたのコード、激遅ぷんぷん丸?今すぐできる7つのチェック項目 PHP編」の感想 | HOME | 買ったものリスト 2013/06/23>>
忍者ブログ[PR]