1 自动加载需要的源代码文件 __autoload()
//文件My_Packages/Debug.php
class MyPackages_Debug{
static function helloWorld(){
print "hello from Debug\n";
}
}
//文件二
function __autoload($className){
//DIRECTORY_SEPARATOR将返回一个系统目录分隔标识符,WIN下是'\',Linux下是'/'
$path=str_replace('_', DIRECTORY_SEPARATOR, $className);
include_once("$path.php");
}
$debug=new MyPackages_Debug();
$debug::helloWorld();
2 通过命名空间融合自动加载__autoload实现自动包含
function __autoload($className){
//匹配包含反斜杠的类名
if(preg_match("/\\\\/", $className)){
$path=str_replace('\\', DIRECTORY_SEPARATOR, $className);
}else{
//DIRECTORY_SEPARATOR将返回一个系统目录分隔标识符,WIN下是'\',Linux下是'/'
$path=str_replace('_', DIRECTORY_SEPARATOR, $className);
}
include_once("$path.php");
}
use MyPackages\Debug;
$debug=new Debug();
$debug::helloWorld();
3 判断对象所属的具体哪个类,用get_class()
判断对象是属于哪个类或接口的家族成员,用instanceof 操作符(要检测的对象在左边)
4 获取类或者对象中的所有public方法 get_class_methods()
注意,method_exists($方法名)可以检测出任意访问权限的方法是否存在,不单单是public
5 获取类或者对象的属性 get_class_vars()
Array{
[属性名]=>VALUE(如果有的话)
}
6 还有很多,比如get_parent_class(),is_subclass_of(),class_implements等等
7 反射API
下面的例子介绍了如何利用反射API,创建一个类,用于动态调用Module对象
class Person{
public $name;
function __construct($n){
$this->name=$n;
}
}
interface Module{
function execute();
}
//下面定义两个实现Module接口的类
class FtpModule implements Module{
function setHost($host){
print "FtpModule::setHost():$host\n";
}
function setUser($user){
print "FtpModule::setHost():$user\n";
}
function execute(){
//Do something
}
}
class PersonModule implements Module{
function setPerson(Person $person){
print "FtpModule::setPerson():{$person->name}\n";
}
function execute(){
//Do something
}
}
//用于动态加载实现了Module接口的对象的类
class ModuleRunner{
//用来保存创建出来的对象
private $modules=array();
private $configData=array(
"PersonModule"=>array('Person'=>'bob'),
"FtpModule"=>array('Host'=>'cow.com','User'=>'Coco543')
);
//根据配置文件初始化对象
function init(){
$interface=new ReflectionClass('Module');
foreach ($this->configData as $moduleName=>$parmes){
//检测是否存在相对应的模块名,有则创建出来
$moduleClass=new ReflectionClass($moduleName);
//创建出来的类必须是实现了Module接口的
if(!$moduleClass->isSubclassOf($interface)){
throw new Exception("Unknow module type: $moduleName");
}
$module=$moduleClass->newInstance();
//获取创建的类的所有方法
$methods=$moduleClass->getMethods();
foreach ($methods as $method){
$this->handleMethod($module, $method, $parmes);
}
array_push($this->modules, $module);
}
}
//操控方法
function handleMethod(Module $module,ReflectionMethod $method,$parmes){
$name=$method->getName();
$args=$method->getParameters();
//方法必须是以set开头,而且参数只有一个
if(count($args)!=1 || stripos($name,'set')>0){
return false;
}
//方法名去掉set之后,首字母大写
$property=ucfirst(substr($name, 3));
if(!isset($parmes[$property])){
return false;
}
//获取参数限定类型
$arg_class=$args[0]->getClass();
if(empty($arg_class)){
//执行一个反射方法
$method->invoke($module,$parmes[$property]);
}else{
$method->invoke($module,$arg_class->newInstance($parmes[$property]));
}
}
}
(new ModuleRunner())->init();