<?php
/**
* 需求:
* 创建一个类来动态调用Module对象,
* 即该类可以自由加载第三方插件并集成进已有的系统,而不需要把第三方的代码硬编码进原有的代码。
*/
class Person {
public $name;
function __construct($name)
{
$this->name = $name;
}
} interface Module
{
public function execute();
} class PersonModule implements Module
{
public function setPerson(Person $person)
{
echo 'PersonModule::setPerson():'.$person->name.PHP_EOL;
} public function execute()
{
echo __METHOD__.PHP_EOL;
}
} class FtpModule implements Module
{
public function setHost($host)
{
echo 'FtpModule::setHost():'.$host.PHP_EOL;
} public function setUser($user)
{
echo 'FtpModule::setUser():'.$user.PHP_EOL;
} public function execute()
{
echo __METHOD__.PHP_EOL;
}
} class ModuelRunner
{
// 定义配置 要加载的模型名和要调用的setXxx()函数
private $configData = [
'PersonModule' => ['person' => 'bob'],
'FtpModule' => ['host' => 'example', 'user' => 'anon']
];
// 保存实例化的模型对象
private $modules = []; // 初始化 创建正确的Module对象
public function init()
{
$interface = new ReflectionClass('Module');
foreach ($this->configData as $moduleName => $params) {
$module_class = new ReflectionClass($moduleName);
// 确保模块类属于Module类型
if (!$module_class->isSubclassOf($interface)) {
throw new Exception('unkonwn module type:'.$moduleName);
}
// 从指定的参数创建一个新的类实例
$module = $module_class->newInstance();
// 获得类中的所有方法
foreach ($module_class->getMethods() as $method) {
$this->handleMethod($module, $method, $params);
}
// 保存模型对象
$this->modules[$moduleName] = $module;
}
} // 检验并调用setXxx()方法
public function handleMethod(Module $module,ReflectionMethod $method, $params)
{
// 获取方法名字
$name = $method->getName();
// 获取 ReflectionParmeter 对象组成的数组
$args = $method->getParameters(); // 规定所有的setter方法必须带有单个参数:字符串或者对象
if (count($args)!=1 || substr($name, 0, 3) != 'set') {
return false;
} // 获取setXxx方法的参数值
$property = strtolower(substr($name, 3));
if (!isset($params[$property])) {
return false;
} // 判断参数是否是对象
$arg_class = $args[0]->getClass();
if (empty($arg_class)) {
// 否 执行
$method->invoke($module, $params[$property]);
} else {
// 是
$method->invoke($module, $arg_class->newInstance($params[$property]));
}
} public function __get($name)
{
if ($name == 'modules') {
return $this->modules;
}
} } echo '<pre>';
$test = new ModuelRunner();
$test->init();
echo '<hr>调用execute()<br>';
$module_obj = $test->modules;
$module_obj['FtpModule']->execute();
$module_obj['PersonModule']->execute();

反射API(二)的更多相关文章

  1. Civil 3D API二次开发学习指南

    Civil 3D构建于AutoCAD 和 Map 3D之上,在学习Civil 3D API二次开发之前,您至少需要了解AutoCAD API的二次开发,你可以参考AutoCAD .NET API二次开 ...

  2. 反射——反射API,使用反射创建数组

    反射API Java.lang.Reflect库 ①   Class类与Java.lang.Reflect类库一起对反射的概念进行支持. ②   java.lang包下: a)         Cla ...

  3. Java反射API研究(1)——注解Annotation

    注解在表面上的意思,只是标记一下这一部分,最好的注解就是代码自身.而在java上,由于注解的特殊性,可以通过反射API获取,这种特性使得注解被广泛应用于各大框架,用于配置内容,代替xml文件配置. 要 ...

  4. PHP反射API的使用、体会、说明

    最近开发支付宝相关功能的时候,由于支付宝的SDK比较落伍,不支持composer的方式加载,使用三方的composer SDK又觉得不放心 为了简化代码的调用方式,使用PHP的反射类针对支付宝官方SD ...

  5. java中的反射(二)

    java中的反射(一):https://www.cnblogs.com/KeleLLXin/p/14060555.html 目录 一.反射 1.class类 2.访问字段 3.调用方法 4.调用构造方 ...

  6. PHP 高级编程(2/5) - 反射API

    PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 此外,反射 API 提供了方法来取出函数.类和方法中的文档注释.通过使用反射API可以分析其他的类.接口.方 ...

  7. 了解一下OOP的反射API

    PHP5的类和对象函数并没有告诉我们类内部的所有一切,而只是报告了它们的公共成员.要充分了解一个类,需要知道其私有成员和保护成员,还要知道其方法所期望的参数 .对此,使用反射API. 1 查看自定义类 ...

  8. PHP反射API

    近期忙着写项目,没有学习什么特别新的东西,所以好长时间没有更新博客.我们的项目用的是lumen,是基于laravel的一个轻量级框架,我看到里面用到了一些反射API机制来帮助动态加载需要的类.判断方法 ...

  9. 用JSON-server模拟REST API(二) 动态数据

    用JSON-server模拟REST API(二) 动态数据 上一篇演示了如何安装并运行 json server , 在这里将使用第三方库让模拟的数据更加丰满和实用. 目录: 使用动态数据 为什么选择 ...

  10. Java学习笔记--反射API

    反射API 1.反射API的介绍 通过反射API可以获取Java程序在运行时刻的内部结构.比如Java类中包含的构造方法.域和方法等元素,并可以与这些元素进行交换.     按照 一般地面向对象的设计 ...

随机推荐

  1. CodeForces 867B Save the problem

    B. Save the problem! http://codeforces.com/contest/867/problem/B time limit per test 2 seconds memor ...

  2. oracle 之 连接查询

    where 连接 select * from a,b //使用的是笛卡尔乘积  显示 a.count*b.count 条数 select * from a,b where a.id=b.id 其实只是 ...

  3. hash进阶:使用字符串hash乱搞的姿势

    前言 此文主要介绍hash的各种乱搞方法,hash入门请参照我之前这篇文章 不好意思hash真的可以为所欲为 在开头先放一下题表(其实就是我题解中的hash题目qwq) 查询子串hash值 必备的入门 ...

  4. (zhuan) 126 篇殿堂级深度学习论文分类整理 从入门到应用

    126 篇殿堂级深度学习论文分类整理 从入门到应用 | 干货 雷锋网 作者: 三川 2017-03-02 18:40:00 查看源网址 阅读数:66 如果你有非常大的决心从事深度学习,又不想在这一行打 ...

  5. 案例2:用一条SQL查询出数学语文成绩都大于80分的学生姓名?

    方法1: 查出科目成绩有小于80分的学生姓名,再约束并去重学生不等于查出来的姓名 select distinct A.name from t_score A where A.name not in(s ...

  6. 【JS】JavaScript中innerHTML与innerText,createTextNode的区别

    innerHTML和innerText 它们都会把元素内内容替换掉,区别在于: innerHTML 会把替换内容里的 HTML 标记解释执行. innerText 会把替换内容里的 HTML 标记原样 ...

  7. Java 数据库篇

    一.简易封装JDBC工具类: package com.jackie.MyBatis.main; import java.sql.Connection; import java.sql.DriverMa ...

  8. 解决:springmvc中接收date数据问题

    这里提供三种解决方案. 一.局部转换 :只是对当前Controller类有效 springMVC.xml中添加: <bean class="org.springframework.we ...

  9. JAVA怎样理解面向对象

    一.对象   现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如人类.书桌.计算机.高楼大厦等.人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的.通常都 ...

  10. NET Core 指令启动

    ASP.NET Core 是新一代的 ASP.NET,早期称为 ASP.NET vNext,并且在推出初期命名为ASP.NET 5,但随着 .NET Core 的成熟,以及 ASP.NET 5的命名会 ...