当前位置: 首页 > news >正文

呼伦贝尔市建设局网站/怎么自己创建网址

呼伦贝尔市建设局网站,怎么自己创建网址,做苗木网站哪家好,哪些网站可以做移动端模板反射在每个面向对象的编程语言中都存在,它的主要目的就是在运行时分析类或者对象的状态,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。 反射是操纵面向对象范型中元模型的 API,可用于构建复杂,可扩展的…

反射在每个面向对象的编程语言中都存在,它的主要目的就是在运行时分析类或者对象的状态,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。 反射是操纵面向对象范型中元模型的 API,可用于构建复杂,可扩展的应用。反射在日常的 Web 开发中其实用的不多,更多的是在偏向底层一些的代码中,比如说框架的底层中依赖注入、对象池、动态代理、自动获取插件列表、自动生成文档以及一些设计模式等等,都会大量运用到反射技术。 PHP 的反射 API 很多,但是常用的一般都是 ReflectionClassReflectionMethod: 1.ReflectionClass 这个是用来获取类的信息,可以简单测试一下:

class Student {private    $name;public function setName($name){$this->name = $name;}protected function getName(){return $this->name;}}
复制代码

获取类的方法列表:

$ref = new ReflectionClass(Student::class);
var_dump($ref->getMethods());
复制代码

返回的是一个 ReflectionMethod 的数组:

array(1) {[0]=>object(ReflectionMethod)#2 (2) {["name"]=>string(7) "setName"["class"]=>string(7) "Student"}
}
复制代码

附上一些常用方法,详细的可以查看文档:

ReflectionClass::getMethods     获取方法的数组
ReflectionClass::getName        获取类名
ReflectionClass::hasMethod      检查方法是否已定义
ReflectionClass::hasProperty    检查属性是否已定义
ReflectionClass::isAbstract     检查类是否是抽象类(abstract)
ReflectionClass::isFinal        检查类是否声明为 final
ReflectionClass::isInstantiable 检查类是否可实例化
ReflectionClass::newInstance    从指定的参数创建一个新的类实例
复制代码

2.ReflectionMethod 这个主要是针对方法的反射,我们可以简单执行一下:

$stu = new Student();
$ref = new ReflectionClass(Student::class);
$method = $ref->getMethod('setName');
$method->invoke($stu, 'john');
var_dump($stu->name);
复制代码

可以输出:

john
复制代码

附上一些常用的方法,详细的可以去看看文档:

ReflectionMethod::invoke        执行
ReflectionMethod::invokeArgs    带参数执行
ReflectionMethod::isAbstract    判断方法是否是抽象方法
ReflectionMethod::isConstructor 判断方法是否是构造方法
ReflectionMethod::isDestructor  判断方法是否是析构方法
ReflectionMethod::isFinal       判断方法是否定义 final
ReflectionMethod::isPrivate     判断方法是否是私有方法
ReflectionMethod::isProtected   判断方法是否是保护方法 (protected)
ReflectionMethod::isPublic      判断方法是否是公开方法
ReflectionMethod::isStatic      判断方法是否是静态方法
ReflectionMethod::setAccessible 设置方法是否访问
复制代码

接下来说一些反射在实际开发中比较常见的应用。

执行私有方法

其实反射不仅可以执行私有方法,还可以读取私有属性。这个主要应用在一些设计不合理的 SDK 里面,一些很好用的方法和属性却不对外开放。

class Student {private    $name;private function setName($name){$this->name = $name;}
}
复制代码

执行私有方法:

$stu = new Student();
$ref = new ReflectionClass($stu);
$method = $ref->getMethod('setName');
$method->setAccessible(true);
$method->invoke($stu, 'john');
复制代码

读取私有属性:

$stu = new Student();
$ref = new ReflectionClass($stu);
$prop = $ref->getProperty('name');
$prop->setAccessible(true);
$val = $prop->getValue($stu);
var_dump($val);
复制代码

动态代理

其实 PHP 有魔术方法,所以实现动态代理已经很简单了,但是通过魔术方法来实现的都不完美,个人理解最好的实现应该还是 JDK 中的动态代理,基于一个接口进行扫描实现实在 PHP 中也可以实现。我们先来看看动态代理在 JDK 中是怎么使用的: 1.首先定义一个实现类的接口,JDK 的动态代理必须基于接口(Cglib则不用)

package com.yao.proxy;
public interface Helloworld {void sayHello();
}
复制代码

2.定义一个实现类,这个类就是要被代理的对象

package com.yao.proxy;
import com.yao.HelloWorld;public class HelloworldImpl implements HelloWorld {public void sayHello() {System.out.print("hello world");}
}
复制代码

3.调用被代理对象方法的实现类

package com.yao.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler{private Object target;public MyInvocationHandler(Object target) {this.target=target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置工作!");Object obj = method.invoke(target,args);System.out.println("后置工作!");return obj;}
复制代码

4.测试

package com.yao.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;public class Demo {public static void main(String[] args) {HelloworldImpl realSubject = new HelloworldImpl();MyInvocationHandler handler = new MyInvocationHandler(realSubject);ClassLoader loader = realSubject.getClass().getClassLoader();Class[] interfaces = realSubject.getClass().getInterfaces();HelloworldImpl proxySubject = (HelloworldImpl) Proxy.newProxyInstance(loader, interfaces, handler);String hello = proxySubject.sayHello();}
}
复制代码

JDK 的动态代理在底层实际上是扫描实现的接口,然后动态生成类的字节码文件。PHP 是动态语言,所以可以用 eval 来实现。 1.定义调度器接口

interface InvocationHandler  
{  function invoke($method, array $arr_args);  
}  
复制代码

2.动态代理实现 定义一个类的 stub:

return new Class($handler,$target) implements %s {  private $handler;  private $target;public function __construct(InvocationHandler $handler, $target) {$this->handler = $handler;  $this->target = $target;}  %s  
};
复制代码

定义一个方法的 stub:

public function %s(%s) {  $args = func_get_args();  $method = explode("::", __METHOD__);  $this->handler->invoke(new ReflectionMethod($this->target, $method[1]), $args);
}
复制代码

Proxy 实现:

final class Proxy  
{   const CLASS_TEMPLATE = class_stub;      //这里显示上面定义的,为了方便阅读const FUNCTION_TEMPLATE = function_stub;    //同上public static function newProxyInstance($target, array $interfaces, InvocationHandler $handler)  {}protected static function generateClass(array $interfaces) {}protected static function checkInterfaceExists(array $interfaces)  {}
}  
复制代码

其中 newProxyInstancegenerateClass 代码:

public static function newProxyInstance($target, array $interfaces, InvocationHandler $handler)  {self::checkInterfaceExists ($interfaces);$code = self::generateClass ($interfaces);return eval($code);}
复制代码
protected static function generateClass(array $interfaces){$interfaceList = implode(',', $interfaces);$functionList = '';foreach ($interfaces as $interface) {$class = new ReflectionClass ($interface);$methods = $class->getMethods();foreach ($methods as $method){$parameters = [];foreach ($method->getParameters() as $parameter){$parameters[] = '$' . $parameter->getName();}$functionList .= sprintf( self::FUNCTION_TEMPLATE, $method->getName(), implode( ',', $parameters ) );}}return sprintf ( self::CLASS_TEMPLATE, $interfaceList, $functionList );}
复制代码

其中generateClass就是通过反射扫描接口方法,然后根据 stub 模板生成方法拼接成代码,最后通过 eval 执行。

2.测试

interface Test1{public function t1();
}
interface Test2{public function t2();
}
class TestImpl implements Test1,Test2{public function t1(){echo 't1';}public function t2(){echo 't2';}
}
$impl = new TestImpl();
class Handler implements InvocationHandler {private $target;public function __construct($impl){$this->target = $impl;}function invoke(ReflectionMethod $method, array $arr_args){echo '前置操作';$method->invokeArgs($this->target, $arr_args);echo '后置操作';}
}$proxy = Proxy::newProxyInstance($impl, ['Test1', 'Test2'], new Handler($impl));
$proxy->t1();
复制代码

输出:

前置操作
t1
后置操作
复制代码

依赖注入

依赖注入是现代化框架中非常常见的一个功能,它必须和服务容器结合使用。用过 Laravel 框架的童鞋应该很熟悉,我们可以在任意需要服务的地方通过类型提示声明,运行时框架就会自动帮我们注入所需要的对象。以 Laravel 框架的源码简单解析下: 在 Laravel 框架中,我们解析一个对象的方法可以这样:

$obj = App::make(ClassName);
复制代码

make方法实际上底层也是调用了Illuminate\Container\Contaiern::build($concrete)这个方法,整理一下源码就是:

public function build($concrete){$reflector = new ReflectionClass($concrete);$constructor = $reflector->getConstructor();if (is_null($constructor)) {return new $concrete;}$dependencies = $constructor->getParameters();$instances = $this->resolveDependencies($dependencies);return $reflector->newInstanceArgs($instances);}
复制代码

实际代码很简单,反射类获取构造方法,然后解析依赖参数,传入执行。

欢迎关我的个人公众号:左手代码

http://www.lbrq.cn/news/1323775.html

相关文章:

  • wordpress 审核文章/seo免费诊断
  • 可以用 我爱乳房做网站名不/广东培训seo
  • WordPress标签加HTML/seo长尾关键词优化
  • 活动策划网站有哪些/seo怎么优化方案
  • 想学网站制作/百度网络营销中心
  • 如何做原创小说网站/百度一下就会知道了
  • 去年做那个网站致富/百度推广账户怎么开
  • 深圳做分销网站设计/全网营销骗局揭秘
  • 做网站有前途吗/seo营销推广服务公司
  • 不喜欢做政府网站运营/seo服务商技术好的公司
  • 东莞大朗疫情最新消息/站长之家seo工具
  • 网站设计的研究方法有哪些/下载百度地图2022最新版
  • 专业团队图片张伟原图/seo内部优化方式包括
  • wordpress缩 图/seo工具包
  • 怎么下载文章到wordpress/杭州网站seo推广
  • 网站制作价格便宜/沪指重上3000点
  • 做营销网站建设挣钱吗/网站友链外链
  • 做刷单哪个网站找小白/外贸网站推广seo
  • 惠州东莞网站建设价格/互联网营销软件
  • 网站一屏做多大/东莞网络推广及优化
  • 安防网站下载/网站seo公司哪家好
  • 机械网站建设注意什么/简述优化搜索引擎的方法
  • 潍坊寿光网站建设/站长之家字体
  • 做外贸首先要做网站/百度关键词推广一年多少钱
  • 怎么做网站咨询/最近一周新闻
  • wordpress收藏本站代码/网络推广深圳有效渠道
  • 做网站一个月30ip/世界杯32强排名
  • 网站和网页不同吗/最有效的广告宣传方式
  • 化妆品品牌策划方案/西安seo关键词排名优化
  • 青县网站建设公司/精准客户信息一条多少钱
  • C++菱形虚拟继承:解开钻石继承的魔咒
  • Python 程序设计讲义(46):组合数据类型——集合类型:集合间运算
  • DNS污染与劫持
  • 基于 xlsx-js-style 的 Excel 导出工具实现导出excel
  • 未授权访问漏洞靶场(redis,MongoDB,Memcached...)
  • 安装redis