PHP面向对象程序设计之类与反射API详解
本文实例讲述了PHP面向对象程序设计之类与反射API。分享给大家供大家参考,具体如下:
了解类
class_exists验证类是否存在
<?php //TaskRunner.php $classname="Task"; $path="tasks/{$classname}.php"; if(!file_exists($path)){ thrownewException("Nosuchfileas{$path}");//抛出异常,类文件不存在 } require_once($path); $qclassname="tasks\\$classname"; if(!class_exists($qclassname)){ thrownewException("Nosuchclassas$qclassname");//抛出异常,类不存在Fatalerror:Uncaughtexception'Exception'withmessage'Nosuchclassastasks\Task' Stacktrace: #0{main} } $myObj=new$qclassname(); $myObj->doSpeak(); ?>
get_class检查对象的类instanceof验证对象是否属于某个类
<?php classCdProduct{} functiongetProduct(){ returnnewCdProduct("ExileonColdharbourLane", "The","Alabama3",10.99,60.33);//返回一个类对象 } $product=getProduct(); if(get_class($product)=='CdProduct'){ print"\$productisaCdProductobject\n"; } ?> <?php classCdProduct{} functiongetProduct(){ returnnewCdProduct("ExileonColdharbourLane", "The","Alabama3",10.99,60.33); } $product=getProduct(); if($productinstanceofCdProduct){ print"\$productisaCdProductobject\n"; } ?>
get_class_methods得到类中所有的方法列表,只获取public的方法,protected,private的方法获取不到。默认的就是public。
<?php classCdProduct{ function__construct(){} functiongetPlayLength(){} functiongetSummaryLine(){} functiongetProducerFirstName(){} functiongetProducerMainName(){} functionsetDiscount(){} functiongetDiscount(){} functiongetTitle(){} functiongetPrice(){} functiongetProducer(){} } print_r(get_class_methods('CdProduct')); ?>
output:
Array ( [0]=>__construct [1]=>getPlayLength [2]=>getSummaryLine [3]=>getProducerFirstName [4]=>getProducerMainName [5]=>setDiscount [6]=>getDiscount [7]=>getTitle [8]=>getPrice [9]=>getProducer )
更多验证
<?php classShopProduct{} interfaceincidental{}; classCdProductextendsShopProductimplementsincidental{ public$coverUrl; function__construct(){} functiongetPlayLength(){} functiongetSummaryLine(){} functiongetProducerFirstName(){} functiongetProducerMainName(){} functionsetDiscount(){} functiongetDiscount(){} functiongetTitle(){return"title\n";} functiongetPrice(){} functiongetProducer(){} } functiongetProduct(){ returnnewCdProduct(); } $product=getProduct();//acquireanobject $method="getTitle";//defineamethodname print$product->$method();//invokethemethod if(in_array($method,get_class_methods($product))){ print$product->$method();//invokethemethod } if(is_callable(array($product,$method))){ print$product->$method();//invokethemethod } if(method_exists($product,$method)){ print$product->$method();//invokethemethod } print_r(get_class_vars('CdProduct')); if(is_subclass_of($product,'ShopProduct')){ print"CdProductisasubclassofShopProduct\n"; } if(is_subclass_of($product,'incidental')){ print"CdProductisasubclassofincidental\n"; } if(in_array('incidental',class_implements($product))){ print"CdProductisaninterfaceofincidental\n"; } ?>
output:
title title title title Array ( [coverUrl]=> ) CdProductisasubclassofShopProduct CdProductisasubclassofincidental CdProductisaninterfaceofincidental
__call方法
<?php classOtherShop{ functionthing(){ print"thing\n"; } functionandAnotherthing(){ print"anotherthing\n"; } } classDelegator{ private$thirdpartyShop; function__construct(){ $this->thirdpartyShop=newOtherShop(); } function__call($method,$args){//当调用未命名方法时执行call方法 if(method_exists($this->thirdpartyShop,$method)){ return$this->thirdpartyShop->$method(); } } } $d=newDelegator(); $d->thing(); ?>
output:
thing
传参使用
<?php classOtherShop{ functionthing(){ print"thing\n"; } functionandAnotherthing($a,$b){ print"anotherthing($a,$b)\n"; } } classDelegator{ private$thirdpartyShop; function__construct(){ $this->thirdpartyShop=newOtherShop(); } function__call($method,$args){ if(method_exists($this->thirdpartyShop,$method)){ returncall_user_func_array( array($this->thirdpartyShop, $method),$args); } } } $d=newDelegator(); $d->andAnotherThing("hi","hello"); ?>
output:
anotherthing(hi,hello)
反射API
fullshop.php
<?php classShopProduct{ private$title; private$producerMainName; private$producerFirstName; protected$price; private$discount=0; publicfunction__construct($title,$firstName, $mainName,$price){ $this->title=$title; $this->producerFirstName=$firstName; $this->producerMainName=$mainName; $this->price=$price; } publicfunctiongetProducerFirstName(){ return$this->producerFirstName; } publicfunctiongetProducerMainName(){ return$this->producerMainName; } publicfunctionsetDiscount($num){ $this->discount=$num; } publicfunctiongetDiscount(){ return$this->discount; } publicfunctiongetTitle(){ return$this->title; } publicfunctiongetPrice(){ return($this->price-$this->discount); } publicfunctiongetProducer(){ return"{$this->producerFirstName}". "{$this->producerMainName}"; } publicfunctiongetSummaryLine(){ $base="{$this->title}({$this->producerMainName},"; $base.="{$this->producerFirstName})"; return$base; } } classCdProductextendsShopProduct{ private$playLength=0; publicfunction__construct($title,$firstName, $mainName,$price,$playLength=78){ parent::__construct($title,$firstName, $mainName,$price); $this->playLength=$playLength; } publicfunctiongetPlayLength(){ return$this->playLength; } publicfunctiongetSummaryLine(){ $base=parent::getSummaryLine(); $base.=":playingtime-{$this->playLength}"; return$base; } } classBookProductextendsShopProduct{ private$numPages=0; publicfunction__construct($title,$firstName, $mainName,$price,$numPages){ parent::__construct($title,$firstName, $mainName,$price); $this->numPages=$numPages; } publicfunctiongetNumberOfPages(){ return$this->numPages; } publicfunctiongetSummaryLine(){ $base=parent::getSummaryLine(); $base.=":pagecount-{$this->numPages}"; return$base; } publicfunctiongetPrice(){ return$this->price; } } /* $product1=newCdProduct("cd1","bob","bobbleson",4,50); print$product1->getSummaryLine()."\n"; $product2=newBookProduct("book1","harry","harrelson",4,30); print$product2->getSummaryLine()."\n"; */ ?> <?php require_once"fullshop.php"; $prod_class=newReflectionClass('CdProduct'); Reflection::export($prod_class); ?>
output:
Class[<user>classCdProductextendsShopProduct]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php53-73 -Constants[0]{ } -Staticproperties[0]{ } -Staticmethods[0]{ } -Properties[2]{ Property[<default>private$playLength] Property[<default>protected$price] } -Methods[10]{ Method[<user,overwritesShopProduct,ctor>publicmethod__construct]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php56-61 -Parameters[5]{ Parameter#0[<required>$title] Parameter#1[<required>$firstName] Parameter#2[<required>$mainName] Parameter#3[<required>$price] Parameter#4[<optional>$playLength=78] } } Method[<user>publicmethodgetPlayLength]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php63-65 } Method[<user,overwritesShopProduct,prototypeShopProduct>publicmethodgetSummaryLine]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php67-71 } Method[<user,inheritsShopProduct>publicmethodgetProducerFirstName]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php17-19 } Method[<user,inheritsShopProduct>publicmethodgetProducerMainName]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php21-23 } Method[<user,inheritsShopProduct>publicmethodsetDiscount]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php25-27 -Parameters[1]{ Parameter#0[<required>$num] } } Method[<user,inheritsShopProduct>publicmethodgetDiscount]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php29-31 } Method[<user,inheritsShopProduct>publicmethodgetTitle]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php33-35 } Method[<user,inheritsShopProduct>publicmethodgetPrice]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php37-39 } Method[<user,inheritsShopProduct>publicmethodgetProducer]{ @@D:\xampp\htdocs\popp-code\5\fullshop.php41-44 } } }
点评:把类看的透彻的一塌糊涂,比var_dump强多了。哪些属性,继承了什么类。类中的方法哪些是自己的,哪些是重写的,哪些是继承的,一目了然。
查看类数据
<?php require_once("fullshop.php"); functionclassData(ReflectionClass$class){ $details=""; $name=$class->getName(); if($class->isUserDefined()){ $details.="$nameisuserdefined\n"; } if($class->isInternal()){ $details.="$nameisbuilt-in\n"; } if($class->isInterface()){ $details.="$nameisinterface\n"; } if($class->isAbstract()){ $details.="$nameisanabstractclass\n"; } if($class->isFinal()){ $details.="$nameisafinalclass\n"; } if($class->isInstantiable()){ $details.="$namecanbeinstantiated\n"; }else{ $details.="$namecannotbeinstantiated\n"; } return$details; } $prod_class=newReflectionClass('CdProduct'); printclassData($prod_class); ?>
output:
CdProductisuserdefined
CdProductcanbeinstantiated
查看方法数据
<?php require_once"fullshop.php"; $prod_class=newReflectionClass('CdProduct'); $methods=$prod_class->getMethods(); foreach($methodsas$method){ printmethodData($method); print"\n----\n"; } functionmethodData(ReflectionMethod$method){ $details=""; $name=$method->getName(); if($method->isUserDefined()){ $details.="$nameisuserdefined\n"; } if($method->isInternal()){ $details.="$nameisbuilt-in\n"; } if($method->isAbstract()){ $details.="$nameisabstract\n"; } if($method->isPublic()){ $details.="$nameispublic\n"; } if($method->isProtected()){ $details.="$nameisprotected\n"; } if($method->isPrivate()){ $details.="$nameisprivate\n"; } if($method->isStatic()){ $details.="$nameisstatic\n"; } if($method->isFinal()){ $details.="$nameisfinal\n"; } if($method->isConstructor()){ $details.="$nameistheconstructor\n"; } if($method->returnsReference()){ $details.="$namereturnsareference(asopposedtoavalue)\n"; } return$details; } ?>
output:
__constructisuserdefined __constructispublic __constructistheconstructor ---- getPlayLengthisuserdefined getPlayLengthispublic ---- getSummaryLineisuserdefined getSummaryLineispublic ---- getProducerFirstNameisuserdefined getProducerFirstNameispublic ---- getProducerMainNameisuserdefined getProducerMainNameispublic ---- setDiscountisuserdefined setDiscountispublic ---- getDiscountisuserdefined getDiscountispublic ---- getTitleisuserdefined getTitleispublic ---- getPriceisuserdefined getPriceispublic ---- getProducerisuserdefined getProducerispublic
获取构造函数参数情况
<?php require_once"fullshop.php"; $prod_class=newReflectionClass('CdProduct'); $method=$prod_class->getMethod("__construct"); $params=$method->getParameters(); foreach($paramsas$param){ printargData($param)."\n"; } functionargData(ReflectionParameter$arg){ $details=""; $declaringclass=$arg->getDeclaringClass(); $name=$arg->getName(); $class=$arg->getClass(); $position=$arg->getPosition(); $details.="\$$namehasposition$position\n"; if(!empty($class)){ $classname=$class->getName(); $details.="\$$namemustbea$classnameobject\n"; } if($arg->isPassedByReference()){ $details.="\$$nameispassedbyreference\n"; } if($arg->isDefaultValueAvailable()){ $def=$arg->getDefaultValue(); $details.="\$$namehasdefault:$def\n"; } if($arg->allowsNull()){ $details.="\$$namecanbenull\n"; } return$details; } ?>
output:
$titlehasposition0 $titlecanbenull $firstNamehasposition1 $firstNamecanbenull $mainNamehasposition2 $mainNamecanbenull $pricehasposition3 $pricecanbenull $playLengthhasposition4 $playLengthhasdefault:78 $playLengthcanbenull
更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。