FooBar 宣言に関する詳細情報が必要になる場合があります。明らかに、1 つが静的メソッドでもう 1 つがインスタンス メソッドであっても、2 つのメソッド foo() を宣言することはできません。
class FooBar
{
public static function foo()
{
return 'I am FooBar::foo().';
}
public function foo()
{
return 'I am FooBar->foo().';
}
}
// result to Fatal error: Cannot redeclare FooBar::foo()
__call()
したがって、次のような魔法のメソッドに到達したいと思います。
class FooBar
{
public $foo = 'I am FooBar->foo().';
// yes we can have a property with the same name than a method
// this is the static method that we want to avoid
public static function foo()
{
return 'I am FooBar::foo().';
}
// this is the method that should be call
public function __call( $method , $arguments = array() )
{
if( isset( $this->$method ) ) // or anything else
{
return $this->$method; // or anything else
}
else
{
// restore fatal error
trigger_error( sprintf( 'Call to undefined method %s::%s()' , get_class( $this ) , $method ) , E_USER_ERROR );
}
}
}
これを実現するには、次のコードを見てください。
$foobar = new FooBar;
try
{
// safe way to detect if a method is static
// @see http://php.net/manual/en/class.reflectionmethod.php
$rfx = new ReflectionMethod( get_class( $foobar ).'::foo' );
if( $rfx->isStatic() )
{
// the method exists and is static
// but we do not want to call it directly
// why not involving the magic public method `__call()`?
// sounds like a plan...
echo $foobar->__call( 'foo' );
}
else
{
// the method exists and is not static
echo $foobar->foo();
}
}
catch( ReflectionException $e )
{
// the method does not exist, let's do some kind of magic
echo $foobar->foo();
}