php面向对象视频笔记之第六章(反射机制与动态代理)
2017-01-25 23:48
811 查看
1、反射机制与动态代理
php的Reflection反射机制
php5添加了一项新的功能:Reflection。这个功能使得程序员可以reflection class,interfacce,function,
method...。通过php代码,就可以得到某类/方法等的所有信息,并且可以和它交互。
反射机制的应用:
动态代理:也叫委托模式,在委托模式中,有两个对象参与处理同个请求,接受请求的对象将请求委托给另一
个对象来处理。
插件系统:利用反射机制自动获取插件列表以及其它的相关信息。
ReflectionFunction应用示例如下即运行结果:
<?php
/**
测试函数注释
*/
function test(){
//code
echo '我是一个测试的函数.<br />';
}
test();
$ref_fun = new ReflectionFunction('test');//参数即函数名
echo $ref_fun->getDocComment();//函数注释
echo '<br />定义在文件:',$ref_fun->getFileName();//函数定义所在的文件
echo '<br />代码开始行:',$ref_fun->getStartLine();//开始行
echo '<br />代码结束行:',$ref_fun->getEndLine();//结束行
try{
new ReflectionFunction('test1');
}catch(ReflectionException $e){
echo '<br />',$e->getMessage();
}
php用反射机制实现动态代理
ref.php
<?php
class A{
function t1(){
echo '我是一个不带参数的方法t1<br />';
}
function t2($str){
echo '我是一个带一个参数的方法t2,参数是:',$str,'<br/ >';
}
private function t3(){
}
static function t4(){
echo '我是一个静态方法<br />';
}
}
$a = new A();
$ref_cls = new ReflectionClass('A');//参数可是类名,也可是类的实例如new ReflectionClass($a);
//获取类中的所有方法
$class_all_methods = $ref_cls->getMethods();
print_r($class_all_methods);
echo '<br />以下是判断类中是否有某个方法的结果.<br />';
//判断类中是否有某个方法 hasMethod 返回布尔值
var_dump($ref_cls->hasMethod('t1'));//bool true
echo '<br />';
var_dump($ref_cls->hasMethod('t')); //bool false
echo '<hr />';
echo '以下是判断类中某个方法权限和调用运行的结果.<br />';
//判断方法的修饰符 public protected private static
//判断方式:is+修饰符 返回的是布尔值
//判断之前要获取类中的方法
$ref_method = $ref_cls->getMethod('t1');//参数是方法名
var_dump($ref_method->isPublic());//是否为公开方法 bool true
echo '<br />';
//执行方法
//静态方法调用 invoke(null,参数);
//普通方法调用 invoke(实例对象,参数);
//私有方法不能被invoke调用。
if($ref_method->isPublic() && !$ref_method->isAbstract()){//是公开且非抽象。
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($a);
}
}
//获取类中的方法的反射类(跟上面的方法作用一样)
$ref_method = new ReflectionMethod('A','t3');//类名+方法名.
var_dump($ref_method->isPublic());//是否为公开方法 bool false
echo '<br />';
$ref_method = new ReflectionMethod('A','t2');
var_dump($ref_method->isStatic());//是否为静态方法 bool true
echo '<br />';
if($ref_method->isPublic() && !$ref_method->isAbstract()){//是公开且非抽象。
if($ref_method->isStatic()){
$ref_method->invoke(null,'yi');
}else{
$ref_method->invoke($a,'yi');
}
}
运行结果:
dynamic.php
<?php
class A{
function showInfoA(){
echo 'function "showInfoA()" of Class A.<br />';
}
}
class C{
function showInfoC(){
echo 'function "showInfoC()" of Class C.<br />';
}
}
class B{
private $obj;
function __construct(){
//$this->obj = new A();//添加单个数组元素
}
function addObj($obj){ //动态添加对象数组
$this->obj[] = $obj; //依次后补数组元素
print_r($this->obj);//查看数组元素
echo '<hr />';
}
function __call($name,$args){
foreach($this->obj as $v){//遍历数组元素
$ref_cls = new ReflectionClass($v);//反射出该对象所在类名
if($ref_cls->hasMethod($name)){//判断该类是否有该方法
$ref_method = $ref_cls->getMethod($name);
if($ref_method->isPublic() && !$ref_method->isAbstract())
{
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($v);
}
}
}
}
/*添加单个对象的情况
$ref_cls = new ReflectionClass($this->obj);
if($ref_cls->hasMethod($name)){
$ref_method = $ref_cls->getMethod($name);
if($ref_method->isPublic() && !$ref_method->isAbstract())
{
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($this->obj);
}
}
}*/
}
}
$b = new B();
$b->addObj(new A());
$b->addObj(new C());
$b->showInfoA();
$b->showInfoC();运行结果:
插件雏形示例:
plugin.php:
<?php
interface Plugin{
function showMenu();
}
class MyPlugin implements Plugin{
//获取插件菜单
function showMenu(){
$menu = array(
array(
'name' => 'My_menu1',
'link' => 'index.php?act=my_link1'
),
array(
'name' => 'My_menu2',
'link' => 'index.php?act=my_link2'
)
);
//print_r($menu);
return $menu;
}
}
class YourPlugin implements Plugin{
//获取插件菜单
function showMenu(){
$menu = array(
array(
'name' => 'Your_menu1',
'link' => 'index.php?act=your_link1'
),
array(
'name' => 'Your_menu2',
'link' => 'index.php?act=your_link2'
)
);
//print_r($menu);
return $menu;
}
}
demo.php:
<?php
//echo __DIR__; 当前目录
include_once __DIR__.'/plugin.php';//在当前目录加上此文件
function get_plugin_menus(){
$all_class = get_declared_classes();
//print_r($all_class);
$menu = $menus = array();
foreach($all_class as $cls){
$ref_cls = new ReflectionClass($cls);
//判断这个类是否实现了某个接口
if($ref_cls->implementsInterface('Plugin')){
//echo $cls,'<br />';
if($ref_cls->hasMethod('showMenu')){
$ref_method = $ref_cls->getMethod('showMenu');
if($ref_method->isPublic() && !$ref_method->isAbstract()){
if($ref_method->isStatic()){
$menu = $ref_method->invoke(null);
}else{
//通过反射类获取类的一个实例
//$menu = $ref_method->invoke(new $cls());
$instance = $ref_cls->newInstance();
$menu = $ref_method->invoke($instance);
}
//合并菜单
$menus = array_merge($menus,$menu);
}
}
}
}
//print_r($menus);
return $menus;
}
$menu_list = get_plugin_menus();
foreach($menu_list as $menu){
echo '<a href="'.$menu['link'].'">'.$menu['name'].'</a><br />';//菜单超链接
}运行结果:
php的Reflection反射机制
php5添加了一项新的功能:Reflection。这个功能使得程序员可以reflection class,interfacce,function,
method...。通过php代码,就可以得到某类/方法等的所有信息,并且可以和它交互。
反射机制的应用:
动态代理:也叫委托模式,在委托模式中,有两个对象参与处理同个请求,接受请求的对象将请求委托给另一
个对象来处理。
插件系统:利用反射机制自动获取插件列表以及其它的相关信息。
ReflectionFunction应用示例如下即运行结果:
<?php
/**
测试函数注释
*/
function test(){
//code
echo '我是一个测试的函数.<br />';
}
test();
$ref_fun = new ReflectionFunction('test');//参数即函数名
echo $ref_fun->getDocComment();//函数注释
echo '<br />定义在文件:',$ref_fun->getFileName();//函数定义所在的文件
echo '<br />代码开始行:',$ref_fun->getStartLine();//开始行
echo '<br />代码结束行:',$ref_fun->getEndLine();//结束行
try{
new ReflectionFunction('test1');
}catch(ReflectionException $e){
echo '<br />',$e->getMessage();
}
php用反射机制实现动态代理
ref.php
<?php
class A{
function t1(){
echo '我是一个不带参数的方法t1<br />';
}
function t2($str){
echo '我是一个带一个参数的方法t2,参数是:',$str,'<br/ >';
}
private function t3(){
}
static function t4(){
echo '我是一个静态方法<br />';
}
}
$a = new A();
$ref_cls = new ReflectionClass('A');//参数可是类名,也可是类的实例如new ReflectionClass($a);
//获取类中的所有方法
$class_all_methods = $ref_cls->getMethods();
print_r($class_all_methods);
echo '<br />以下是判断类中是否有某个方法的结果.<br />';
//判断类中是否有某个方法 hasMethod 返回布尔值
var_dump($ref_cls->hasMethod('t1'));//bool true
echo '<br />';
var_dump($ref_cls->hasMethod('t')); //bool false
echo '<hr />';
echo '以下是判断类中某个方法权限和调用运行的结果.<br />';
//判断方法的修饰符 public protected private static
//判断方式:is+修饰符 返回的是布尔值
//判断之前要获取类中的方法
$ref_method = $ref_cls->getMethod('t1');//参数是方法名
var_dump($ref_method->isPublic());//是否为公开方法 bool true
echo '<br />';
//执行方法
//静态方法调用 invoke(null,参数);
//普通方法调用 invoke(实例对象,参数);
//私有方法不能被invoke调用。
if($ref_method->isPublic() && !$ref_method->isAbstract()){//是公开且非抽象。
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($a);
}
}
//获取类中的方法的反射类(跟上面的方法作用一样)
$ref_method = new ReflectionMethod('A','t3');//类名+方法名.
var_dump($ref_method->isPublic());//是否为公开方法 bool false
echo '<br />';
$ref_method = new ReflectionMethod('A','t2');
var_dump($ref_method->isStatic());//是否为静态方法 bool true
echo '<br />';
if($ref_method->isPublic() && !$ref_method->isAbstract()){//是公开且非抽象。
if($ref_method->isStatic()){
$ref_method->invoke(null,'yi');
}else{
$ref_method->invoke($a,'yi');
}
}
运行结果:
dynamic.php
<?php
class A{
function showInfoA(){
echo 'function "showInfoA()" of Class A.<br />';
}
}
class C{
function showInfoC(){
echo 'function "showInfoC()" of Class C.<br />';
}
}
class B{
private $obj;
function __construct(){
//$this->obj = new A();//添加单个数组元素
}
function addObj($obj){ //动态添加对象数组
$this->obj[] = $obj; //依次后补数组元素
print_r($this->obj);//查看数组元素
echo '<hr />';
}
function __call($name,$args){
foreach($this->obj as $v){//遍历数组元素
$ref_cls = new ReflectionClass($v);//反射出该对象所在类名
if($ref_cls->hasMethod($name)){//判断该类是否有该方法
$ref_method = $ref_cls->getMethod($name);
if($ref_method->isPublic() && !$ref_method->isAbstract())
{
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($v);
}
}
}
}
/*添加单个对象的情况
$ref_cls = new ReflectionClass($this->obj);
if($ref_cls->hasMethod($name)){
$ref_method = $ref_cls->getMethod($name);
if($ref_method->isPublic() && !$ref_method->isAbstract())
{
if($ref_method->isStatic()){
$ref_method->invoke(null);
}else{
$ref_method->invoke($this->obj);
}
}
}*/
}
}
$b = new B();
$b->addObj(new A());
$b->addObj(new C());
$b->showInfoA();
$b->showInfoC();运行结果:
插件雏形示例:
plugin.php:
<?php
interface Plugin{
function showMenu();
}
class MyPlugin implements Plugin{
//获取插件菜单
function showMenu(){
$menu = array(
array(
'name' => 'My_menu1',
'link' => 'index.php?act=my_link1'
),
array(
'name' => 'My_menu2',
'link' => 'index.php?act=my_link2'
)
);
//print_r($menu);
return $menu;
}
}
class YourPlugin implements Plugin{
//获取插件菜单
function showMenu(){
$menu = array(
array(
'name' => 'Your_menu1',
'link' => 'index.php?act=your_link1'
),
array(
'name' => 'Your_menu2',
'link' => 'index.php?act=your_link2'
)
);
//print_r($menu);
return $menu;
}
}
demo.php:
<?php
//echo __DIR__; 当前目录
include_once __DIR__.'/plugin.php';//在当前目录加上此文件
function get_plugin_menus(){
$all_class = get_declared_classes();
//print_r($all_class);
$menu = $menus = array();
foreach($all_class as $cls){
$ref_cls = new ReflectionClass($cls);
//判断这个类是否实现了某个接口
if($ref_cls->implementsInterface('Plugin')){
//echo $cls,'<br />';
if($ref_cls->hasMethod('showMenu')){
$ref_method = $ref_cls->getMethod('showMenu');
if($ref_method->isPublic() && !$ref_method->isAbstract()){
if($ref_method->isStatic()){
$menu = $ref_method->invoke(null);
}else{
//通过反射类获取类的一个实例
//$menu = $ref_method->invoke(new $cls());
$instance = $ref_cls->newInstance();
$menu = $ref_method->invoke($instance);
}
//合并菜单
$menus = array_merge($menus,$menu);
}
}
}
}
//print_r($menus);
return $menus;
}
$menu_list = get_plugin_menus();
foreach($menu_list as $menu){
echo '<a href="'.$menu['link'].'">'.$menu['name'].'</a><br />';//菜单超链接
}运行结果:
相关文章推荐
- PHP中使用反射机制实现动态代理
- Java的反射机制与动态代理学习笔记
- 15. JAVA 反射机制 Part 2(动态代理、类的生命周期、工厂设计模式) ----- 学习笔记
- PHP 反射机制实现动态代理的代码
- java学习笔记---类型信息(type information)、反射机制与动态代理
- Java学习笔记:反射与代理机制(静态、动态)
- PHP 反射机制实现动态代理的代码
- 利用php反射机制实现动态代理模式
- PHP反射机制实现动态代理的代码
- PHP 反射机制实现动态代理的代码
- PHP实现依赖注入-使用反射机制和动态代理技术 - 简单思想(咋个办呢 zgbn)
- java学习笔记13--反射机制与动态代理
- PHP 反射机制实现动态代理的代码
- Java的反射机制和动态代理
- 韩顺平php视频笔记79 80 错误和异常处理的机制 错误处理器 错误触发器
- 韩顺平php视频笔记62-67 php面向对象
- JAVA的反射机制与动态代理
- Java学习笔记之反射的应用-动态代理
- java动态代理机制和反射机制间的联系
- php 反射机制实现代理模式