利用php中的eval来模拟java中的动态代理
2010-04-28 10:44
537 查看
使用java中的动态代理可以完成很多事情,比如将业务实例进行托管,实现AOP等,但是Php中没有实现这样的东西,昨天突然想到其实可以通过eval来模拟一个动态代理机制。php比java不同的是,php是不需要编译的,因此只要我们能够动态生成一段代码,然后用eval来执行就可以达到效果。代码如下:
其实从这个例子可以推出来,我们甚至可以模拟asm的相关功能,而且实现要比java简单很多。看来以前没有挖掘php的功能呀,这个语言被我低估了。
/** * 代理实现类 */ interface IInvocationHandler { function invoke($method, array $arr_args); } /** * 代理类 */ final class Proxy { const CLASS_TEMPLATE = ' final class %s implements %s { private $handler; public function __construct(IInvocationHandler $handler) { $this->handler = $handler; } %s } '; const FUNCTION_TEMPLATE = ' public function %s(%s) { $arr_args = func_get_args (); $arr_method = explode("::", __METHOD__); $this->handler->invoke ( $arr_method[1], $arr_args ); } '; public static function newProxyInstance(array $arr_interface, IInvocationHandler $handler) { $className = self::getClassName ( $arr_interface ); if (class_exists ( $className )) { return new $className ( $handler ); } self::checkInterfaceExists ( $arr_interface ); self::generateClass ( $arr_interface ); return new $className ( $handler ); } protected static function generateClass(array $arr_interface) { $className = self::getClassName ( $arr_interface ); $interfaceList = implode ( ',', $arr_interface ); $functionList = ''; foreach ( $arr_interface as $interface ) { $class = new ReflectionClass ( $interface ); $arr_method = $class->getMethods (); foreach ( $arr_method as $method ) { $methodName = $method->getName (); $arr_parameter = $method->getParameters (); $parameterArray = array (); foreach ( $arr_parameter as $parameter ) { $parameterName = $parameter->getName (); $parameterArray [] = '$' . $parameterName; } $parameterList = implode ( ',', $parameterArray ); } $functionList .= sprintf ( self::FUNCTION_TEMPLATE, $methodName, $parameterList ); } $code = sprintf ( self::CLASS_TEMPLATE, $className, $interfaceList, $functionList ); eval ( $code ); } protected static function checkInterfaceExists(array $arr_interface) { foreach ( $arr_interface as $interface ) { if (! interface_exists ( $interface )) { throw new Exception ( "interface $interface do not loaded" ); } } } protected static function getClassName(array $arr_interface) { return 'Class_' . implode ( '_', $arr_interface ) . '_Implementation'; } } class Test implements ITest1, ITest2 { /** * @see ITest1::test1() * * @param unknown_type $arg1 * @param unknown_type $arg2 */ function test1($arg1, $arg2) { echo "Test::test1($arg1, $arg2)/n"; return "ok"; } /** * @see ITest2::test2() * */ function test2() { echo "Test::test2()/n"; return "failed"; } } class Target implements IInvocationHandler { private $target; public function __construct() { $this->target = new Test ( ); } /** * @see IInvocationHandler::invoke() * * @param ReflectionMethod $method * @param array $arr_args */ function invoke($methodName, array $arr_args) { $method = new ReflectionMethod ( 'Test', $methodName ); echo "before call method $methodName/n"; $ret = $method->invokeArgs ( $this->target, $arr_args ); echo "after call method $methodName return $ret/n"; return $ret; } } interface ITest1 { function test1($arg1, $arg2); } interface ITest2 { function test2(); } $proxy = Proxy::newProxyInstance ( array ('ITest1', 'ITest2' ), new Target ( ) ); $proxy->test2 (); $proxy = Proxy::newProxyInstance ( array ('ITest1' ), new Target ( ) ); $proxy->test1 ( 'a', 1 );
其实从这个例子可以推出来,我们甚至可以模拟asm的相关功能,而且实现要比java简单很多。看来以前没有挖掘php的功能呀,这个语言被我低估了。
相关文章推荐
- 利用java 的动态代理模拟spring的AOP
- Java利用动态代理模拟实现Spring的AOP(面向切面编程)功能的小实践
- 在java中利用动态编译实现eval
- Java动态代理三--模拟AOP实现
- 模拟实现Java动态代理机制
- Java动态代理实现模拟RMI远程方法调用
- JAVA动态代理 ps:模拟jdk
- java中利用动态代理,生成"空"对象的例子
- Java利用Proxy实现动态代理
- JAVA 动态替换代理IP并模拟POST请求第二弹<转自ITeye>
- Java动态代理连接数据库,模拟连接池
- 模拟JDK动态代理 ; 自己动手模拟实现java动态代理
- 关于利用动态代理手写数据库连接池的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection
- java动态代理案例:Spring中Aop功能的模拟
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- 在java中利用动态编译实现eval
- 在Java中利用动态代理实现数据库连接与事务的自动管理
- 又一次闲来无聊,使用Java的动态代理机制来模拟AOP
- java利用反射实现动态代理示例
- Java动态代理三——模拟AOP实现