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程序设计有所帮助。