PHP面向对象程序设计之类与反射API详解
本文实例讲述了php面向对象程序设计之类与反射api。分享给大家供大家参考,具体如下:
了解类
class_exists验证类是否存在
<?php // taskrunner.php $classname = "task"; $path = "tasks/{$classname}.php"; if ( ! file_exists( $path ) ) { throw new exception( "no such file as {$path}" ); //抛出异常,类文件不存在 } require_once( $path ); $qclassname = "tasks\\$classname"; if ( ! class_exists( $qclassname ) ) { throw new exception( "no such class as $qclassname" ); //抛出异常,类不存在fatal error: uncaught exception 'exception' with message 'no such class as tasks\task' stack trace: #0 {main} } $myobj = new $qclassname(); $myobj->dospeak(); ?>
get_class 检查对象的类 instanceof 验证对象是否属于某个类
<?php class cdproduct {} function getproduct() { return new cdproduct( "exile on coldharbour lane", "the", "alabama 3", 10.99, 60.33 ); // 返回一个类对象 } $product = getproduct(); if ( get_class( $product ) == 'cdproduct' ) { print "\$product is a cdproduct object\n"; } ?> <?php class cdproduct {} function getproduct() { return new cdproduct( "exile on coldharbour lane", "the", "alabama 3", 10.99, 60.33 ); } $product = getproduct(); if ( $product instanceof cdproduct ) { print "\$product is a cdproduct object\n"; } ?>
get_class_methods 得到类中所有的方法列表,只获取public的方法,protected,private的方法获取不到。默认的就是public。
<?php class cdproduct { function __construct() { } function getplaylength() { } function getsummaryline() { } function getproducerfirstname() { } function getproducermainname() { } function setdiscount() { } function getdiscount() { } function gettitle() { } function getprice() { } function getproducer() { } } 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 class shopproduct {} interface incidental {}; class cdproduct extends shopproduct implements incidental { public $coverurl; function __construct() { } function getplaylength() { } function getsummaryline() { } function getproducerfirstname() { } function getproducermainname() { } function setdiscount() { } function getdiscount() { } function gettitle() { return "title\n"; } function getprice() { } function getproducer() { } } function getproduct() { return new cdproduct(); } $product = getproduct(); // acquire an object $method = "gettitle"; // define a method name print $product->$method(); // invoke the method if ( in_array( $method, get_class_methods( $product ) ) ) { print $product->$method(); // invoke the method } if ( is_callable( array( $product, $method) ) ) { print $product->$method(); // invoke the method } if ( method_exists( $product, $method ) ) { print $product->$method(); // invoke the method } print_r( get_class_vars( 'cdproduct' ) ); if ( is_subclass_of( $product, 'shopproduct' ) ) { print "cdproduct is a subclass of shopproduct\n"; } if ( is_subclass_of( $product, 'incidental' ) ) { print "cdproduct is a subclass of incidental\n"; } if ( in_array( 'incidental', class_implements( $product )) ) { print "cdproduct is an interface of incidental\n"; } ?>
output:
title title title title array ( [coverurl] => ) cdproduct is a subclass of shopproduct cdproduct is a subclass of incidental cdproduct is an interface of incidental
__call方法
<?php class othershop { function thing() { print "thing\n"; } function andanotherthing() { print "another thing\n"; } } class delegator { private $thirdpartyshop; function __construct() { $this->thirdpartyshop = new othershop(); } function __call( $method, $args ) { // 当调用未命名方法时执行call方法 if ( method_exists( $this->thirdpartyshop, $method ) ) { return $this->thirdpartyshop->$method( ); } } } $d = new delegator(); $d->thing(); ?>
output:
thing
传参使用
<?php class othershop { function thing() { print "thing\n"; } function andanotherthing( $a, $b ) { print "another thing ($a, $b)\n"; } } class delegator { private $thirdpartyshop; function __construct() { $this->thirdpartyshop = new othershop(); } function __call( $method, $args ) { if ( method_exists( $this->thirdpartyshop, $method ) ) { return call_user_func_array( array( $this->thirdpartyshop, $method ), $args ); } } } $d = new delegator(); $d->andanotherthing( "hi", "hello" ); ?>
output:
another thing (hi, hello)
反射api
fullshop.php
<?php class shopproduct { private $title; private $producermainname; private $producerfirstname; protected $price; private $discount = 0; public function __construct( $title, $firstname, $mainname, $price ) { $this->title = $title; $this->producerfirstname = $firstname; $this->producermainname = $mainname; $this->price = $price; } public function getproducerfirstname() { return $this->producerfirstname; } public function getproducermainname() { return $this->producermainname; } public function setdiscount( $num ) { $this->discount=$num; } public function getdiscount() { return $this->discount; } public function gettitle() { return $this->title; } public function getprice() { return ($this->price - $this->discount); } public function getproducer() { return "{$this->producerfirstname}". " {$this->producermainname}"; } public function getsummaryline() { $base = "{$this->title} ( {$this->producermainname}, "; $base .= "{$this->producerfirstname} )"; return $base; } } class cdproduct extends shopproduct { private $playlength = 0; public function __construct( $title, $firstname, $mainname, $price, $playlength=78 ) { parent::__construct( $title, $firstname, $mainname, $price ); $this->playlength = $playlength; } public function getplaylength() { return $this->playlength; } public function getsummaryline() { $base = parent::getsummaryline(); $base .= ": playing time - {$this->playlength}"; return $base; } } class bookproduct extends shopproduct { private $numpages = 0; public function __construct( $title, $firstname, $mainname, $price, $numpages ) { parent::__construct( $title, $firstname, $mainname, $price ); $this->numpages = $numpages; } public function getnumberofpages() { return $this->numpages; } public function getsummaryline() { $base = parent::getsummaryline(); $base .= ": page count - {$this->numpages}"; return $base; } public function getprice() { return $this->price; } } /* $product1 = new cdproduct("cd1", "bob", "bobbleson", 4, 50 ); print $product1->getsummaryline()."\n"; $product2 = new bookproduct("book1", "harry", "harrelson", 4, 30 ); print $product2->getsummaryline()."\n"; */ ?> <?php require_once "fullshop.php"; $prod_class = new reflectionclass( 'cdproduct' ); reflection::export( $prod_class ); ?>
output:
class [ <user> class cdproduct extends shopproduct ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 53-73 - constants [0] { } - static properties [0] { } - static methods [0] { } - properties [2] { property [ <default> private $playlength ] property [ <default> protected $price ] } - methods [10] { method [ <user, overwrites shopproduct, ctor> public method __construct ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 56 - 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> public method getplaylength ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 63 - 65 } method [ <user, overwrites shopproduct, prototype shopproduct> public method getsummaryline ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 67 - 71 } method [ <user, inherits shopproduct> public method getproducerfirstname ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 17 - 19 } method [ <user, inherits shopproduct> public method getproducermainname ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 21 - 23 } method [ <user, inherits shopproduct> public method setdiscount ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 25 - 27 - parameters [1] { parameter #0 [ <required> $num ] } } method [ <user, inherits shopproduct> public method getdiscount ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 29 - 31 } method [ <user, inherits shopproduct> public method gettitle ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 33 - 35 } method [ <user, inherits shopproduct> public method getprice ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 37 - 39 } method [ <user, inherits shopproduct> public method getproducer ] { @@ d:\xampp\htdocs\popp-code\5\fullshop.php 41 - 44 } } }
点评:把类看的透彻的一塌糊涂,比var_dump强多了。哪些属性,继承了什么类。类中的方法哪些是自己的,哪些是重写的,哪些是继承的,一目了然。
查看类数据
<?php require_once("fullshop.php"); function classdata( reflectionclass $class ) { $details = ""; $name = $class->getname(); if ( $class->isuserdefined() ) { $details .= "$name is user defined\n"; } if ( $class->isinternal() ) { $details .= "$name is built-in\n"; } if ( $class->isinterface() ) { $details .= "$name is interface\n"; } if ( $class->isabstract() ) { $details .= "$name is an abstract class\n"; } if ( $class->isfinal() ) { $details .= "$name is a final class\n"; } if ( $class->isinstantiable() ) { $details .= "$name can be instantiated\n"; } else { $details .= "$name can not be instantiated\n"; } return $details; } $prod_class = new reflectionclass( 'cdproduct' ); print classdata( $prod_class ); ?>
output:
cdproduct is user defined
cdproduct can be instantiated
查看方法数据
<?php require_once "fullshop.php"; $prod_class = new reflectionclass( 'cdproduct' ); $methods = $prod_class->getmethods(); foreach ( $methods as $method ) { print methoddata( $method ); print "\n----\n"; } function methoddata( reflectionmethod $method ) { $details = ""; $name = $method->getname(); if ( $method->isuserdefined() ) { $details .= "$name is user defined\n"; } if ( $method->isinternal() ) { $details .= "$name is built-in\n"; } if ( $method->isabstract() ) { $details .= "$name is abstract\n"; } if ( $method->ispublic() ) { $details .= "$name is public\n"; } if ( $method->isprotected() ) { $details .= "$name is protected\n"; } if ( $method->isprivate() ) { $details .= "$name is private\n"; } if ( $method->isstatic() ) { $details .= "$name is static\n"; } if ( $method->isfinal() ) { $details .= "$name is final\n"; } if ( $method->isconstructor() ) { $details .= "$name is the constructor\n"; } if ( $method->returnsreference() ) { $details .= "$name returns a reference (as opposed to a value)\n"; } return $details; } ?>
output:
__construct is user defined __construct is public __construct is the constructor ---- getplaylength is user defined getplaylength is public ---- getsummaryline is user defined getsummaryline is public ---- getproducerfirstname is user defined getproducerfirstname is public ---- getproducermainname is user defined getproducermainname is public ---- setdiscount is user defined setdiscount is public ---- getdiscount is user defined getdiscount is public ---- gettitle is user defined gettitle is public ---- getprice is user defined getprice is public ---- getproducer is user defined getproducer is public
获取构造函数参数情况
<?php require_once "fullshop.php"; $prod_class = new reflectionclass( 'cdproduct' ); $method = $prod_class->getmethod( "__construct" ); $params = $method->getparameters(); foreach ( $params as $param ) { print argdata( $param )."\n"; } function argdata( reflectionparameter $arg ) { $details = ""; $declaringclass = $arg->getdeclaringclass(); $name = $arg->getname(); $class = $arg->getclass(); $position = $arg->getposition(); $details .= "\$$name has position $position\n"; if ( ! empty( $class ) ) { $classname = $class->getname(); $details .= "\$$name must be a $classname object\n"; } if ( $arg->ispassedbyreference() ) { $details .= "\$$name is passed by reference\n"; } if ( $arg->isdefaultvalueavailable() ) { $def = $arg->getdefaultvalue(); $details .= "\$$name has default: $def\n"; } if ( $arg->allowsnull() ) { $details .= "\$$name can be null\n"; } return $details; } ?>
output:
$title has position 0 $title can be null $firstname has position 1 $firstname can be null $mainname has position 2 $mainname can be null $price has position 3 $price can be null $playlength has position 4 $playlength has default: 78 $playlength can be null
更多关于php相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《php基本语法入门教程》、《php运算与运算符用法总结》、《php网络编程技巧总结》、《php数组(array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家php程序设计有所帮助。
上一篇: thinkPHP交易详情查询功能详解
下一篇: Java实现的猴子吃桃问题算法示例