442phpclass类简单用法总结.docx
《442phpclass类简单用法总结.docx》由会员分享,可在线阅读,更多相关《442phpclass类简单用法总结.docx(12页珍藏版)》请在冰豆网上搜索。
442phpclass类简单用法总结
一:
结构和调用(实例化):
classclassName{},调用:
$obj=newclassName();当类有构造函数时,还应传入参数。
如$obj=newclassName($v,$v2…);
二:
构造函数和析构函数:
1、构造函数用于初始化:
使用__construct(),可带参数。
2、但析构函数不能带参数(用于在销去一个类之前执行一些操作或功能)。
析构函数用__destruct()做名称。
在脚本执行结束时,会销掉内存中的对象,因此可不用析造函数,但有些比如COOKIE等,就应当要用此函数销掉。
知识点:
在PHP4中也提供了构造函数,但使用的是与类同名的类方法,在PHP5仍能兼容这种做法,当一个类中没有包含__construct时,会查找与类同名的方法,如果找到,就认为是构造函数,如下:
classtest
{var$b;
functiontest(){ $this->b=5;}
functionaddab($c){ return$this->b+$c;}
}
$a=newtest(); echo$a->addab(4);//返回9
3、PHP不会自动调用父类的构造函数(不支持构造函数重载),必须使用parent关键字显式地调用。
classemployee{
function__construct()….
}
classManagerextentsEmployee{
function__construct(){
parent:
:
_construct();
echo‘这个子类的父类构造函数调用了!
’;
}
}
当然也可以调用与该实例没有任何关系的其它类的构造函数。
只需在__construct()前加上类名即可。
如:
otherClassName:
:
__construct();
类的主家庭成员:
属性、方法、常量、静态成员
三、类的属性:
有两种方法对类的属性赋值或取值。
1、使用公共作用域public关键词。
2、使用__set()和__get()来分别赋值和取值,前者称为设置方法(setter)或修改方法(mutator),后者称为访问方法(accessor)或获取方法(getter)。
建议使用这种方法:
优点:
A、可在__set()统一进行数据验证。
B、便于统一管理属性。
注意:
第一:
__set()和__get()只对私有属性起作用,对于用public定义的属性,它们两个都懒理搭理,如下:
classtest{
protected$a=9,$b=2,$c;
public$d;
function__set($n,$v){ $this->$n=$v+2;}
function__get($name){return$this->$name+2;}
}
$a=newtest();
$a->b=5;echo“
”; echo$a->b;
实例只对$a,$b,$c的设置会经过__set和__get过滤与返回,对于$d,就不会起作用。
如$a->d=5,再返回还是5。
第二:
__set($n,$v)要带两个参数。
而__get($n)只能有一个参数。
实例:
classtest{
private$a=5,$b=6,$c;
function__set($n,$v)
{
if($n==’a'&&$n>0)
$this->$n=$v;
else
$this->$n=$v+2;
}
function__get($name)
{
return$this->$name;//如果改为return$this->$name+$this->addab(); 如调用a的值,实际返回的是a+a+b的值。
默认为5+5+6=16。
}
functionaddab()
{ return$this->a+$this->b; }
}
$e=newtest();
$e->a=11; //注意写法:
类的内部用$this->$n即变量的写法,但外部实例要用$e->a的方式。
$e->b=12; //get14
$e->k=22;
类的属性可自由扩展,如上例的k,不管是否用__set,当一个实例建立起来后,可以用$e->newProperty=xx;直接来创造一个属性,但不建议这么做。
四、类的方法:
理解成类当中的函数即可。
调用:
1、内部调用:
可使用$this->Fanname();或$this->addab()或test:
:
addab();
2、实例化调用时,用$e->addab();即可。
对于在该方法中没有使用$this关键字的,如上例中的:
functionaddab(){ return$this->a+$this->b; }
改为:
functionaddab(){ return25; }那在在外部实例调用该方法,也可用“$e:
:
addab();”或“test:
:
addab();”
五、类的常量:
如果类的属性理解成类中的变量,那么类的常量和变量是不一样的,其定义方法为:
classtest{
private$a;
constPI=’3.14′;
…..
//在类中调用上面的常量用两种方法,“$this:
:
PI”,或“类名:
:
PI”,这里就是test:
:
PI,如下:
functiongetvalue(){
return$this->a*$this:
:
PI;//或$this->a*test:
:
PI,用this关键字或类名均可,但都要用双冒号。
}
}
$e=newtest();
$e->PI=5; //注意,这里用->只是创造了一个也是名为PI的属性,而不是改变类中的PI常量的值。
echo$e:
:
PI;//这个才是调用类的常量。
常量只能用双冒号:
:
来调用。
并且不能更改其值。
在类外部实例化后调用类常量同样也有两种方法。
方法为:
“$e:
:
PI” 或“test:
:
PI”,共同点是都要用冒号,不同点是外部不能用this关键字,只能用实例名,但类名:
:
PI是通用的。
六、类的静态成员(静态属性或静态方法):
如果需要创建供所有类的实例共享的字段或方法。
就得用静态成员。
有两个特征:
1、静态成员是共产主义者,它让脚本上的所有该类的实例调用,但不能借助类的特定实例名调用,而是在类的外部,统一使用“类名:
:
$成员名”的方式调用。
而类的内部则统一使用“self:
:
$成员名”来调用。
2、当每一次新创建实例时,静态成员会从上次创建的实例最后值开始重新计算,而不是类中初始的值开始计算。
3、对于用public定义的静态成员,可以在外部更改它的值。
private等则不行。
classtest{
publicstatic$v=0;
function__construct(){ self:
:
$v++;}
staticfunctiongetV(){ returnself:
:
$v;}
}
$a=newtest();
echotest:
:
getV();//返回1
$b=newtest();
echotest:
:
getV(); //返回2
test:
:
$v=8; //由于public定义的成员,改变静态成员的值。
$c=newtest();
echotest:
:
getV(); //返回9
七、关键字:
(一)this关键字:
用于类的内部指代类的本身。
来访问属性或方法或常量,如$this->属性名或方法名。
$this:
:
常量名。
this还可以用在该类的子类中,来指代本身的属性或方法。
(二)双冒号“:
:
”关键字:
用于调用常量、静态成员。
(三)self关键字:
在类的内部与双冒号配合调用静态成员,如self:
:
$staticVar.,在类的内部,不能用$this来调用静态成员。
(四)__toString():
在类中使用__toString(),用于将类转成字串并打印类,用处不大:
如:
classtest{ public$p;
publicfunction__toString(){ returnvar_export($this,TRUE); }
}
$a=newtest();
echo$a;//输出:
test:
:
__set_state(array(‘p’=>NULL,)),或写成:
echo$a->__toString();
(五)__clone():
当克隆对象时,这个关键字才会发生作用,用于更改克隆时某些值。
(六)__call():
方法重载,参下面示例:
classcB{
function__call($method,$n){
if($method==’showVarType’){
if(is_numeric($n[0])){ //不能用$n。
要用$n[0];
$this->displayNum();
}elseif(is_array($n[0])){
$this->displayArr();
}else{
$this->displayOther();
}
}
}
functiondisplayNum(){
echo‘
这是数字!
’;
}
functiondisplayArr(){
echo‘
这是数组!
’;
}
functiondisplayOther(){
echo‘
不是数组也不是数字!
’;
}
}
$x=’a';
$y=array(‘a’,'b’);
$b=newcB;
$b->showVarType($x);//不是数组也不是数字
$b->showVarType($y);//这是数组
注意,不能在类中定义showVarType()方法,否则代码不能用。
(七)extends:
继承:
如classa{} classbextendsa{}类b继承了类a
附:
记忆:
以后统一在调用方法或属性时用“->“,调用常量则用双冒号“:
:
”,不会搞晕。
八、方法和属性的作用域:
共有6种:
public(默认,可省略,也等同于php6的var声明),private(私有,也不能由子类使用),protected(私有,但可由子类使用),abstract(抽象,参下文),final(阻止在子类中覆盖—也称重载,阻止被继承,用于修饰类名及方法,如finalclasstest{finalfunctionfun(){}},但不能用于属性),static(静态)
九:
抽象类和抽象方法(abstract——注意:
没有所谓抽象属性):
抽象可以理解成父类为子类定义了一个模板或基类。
作用域abstract只在父类中声明,但在子类中实现。
注意事项:
1、抽象类不能被实例化,只能被子类(具体类)继承后实现。
2、抽象类必须在其子类中实现该抽象类的所有抽象方法。
否则会出错。
3、在抽象方法中,只是声明,但不能具体实现:
如abstractfunctiongettow(){return$this->p;}是错的,只能声明这个方法:
abstractfunctiongettow();(连方括号{}都不要出现),抽象方法和抽象类主要用于复杂的类层次关系中。
该层次关系需要确保每一个子类都包含并重载了某些特定的方法。
这也可以通过接口实现
4、属性不能被命名为抽象属性,如abstract$p=5是错的。
5、只有声明为抽象的类可以声明抽象方法,但如果方法声明为抽象,就不能具体实现。
如:
abstractclassEmployee
{
abstractfunctiona(…);
abstractfunctionb(…);
}
以后再对这个父类扩展,组成各种子类(如经理,员工,出纳)。
6、抽象类中,如果要实现具体的方法,不能声明为抽象。
这样可能实际意义更大。
可以把几个类库中共同的部分提取到抽象类中,其它的类继承抽象类即可。
如下:
abstractclassBaseShop{
ConstTAX=0.06; //在抽象类中定义常量
publicfunctionbuy($gid){ //如果定义为抽象方法abstractfunctionbuy()就不能在这里实现主体。
echo(‘你购买了ID为:
’.$gid.’的商品’);
}
publicfunctionsell($gid){
echo(‘你卖了ID为:
’.$gid.’的商品’);
}
publicfunctionview($gid){
echo(‘你查看了ID为:
’.$gid.’的商品’);
}
}
classBallShopextendsBaseShop{
var$itme_id=null;
publicfunction__construct()
{
$this->itme_id=2314;
}
publicfunctionopen()
{
$this->sell($this->itme_id);
}
publicfunctiongetTax()
{
echoprintf(‘
平均税率是%d%%。
’,$this:
:
TAX*100);
}
}
$s=newBallShop;
$s->open();//你卖了ID为:
2314的商品
$shop->getTax();
十:
类型提示:
注意,类型提示功能只能用于参数为对象的提示,而无法用于为整数,字串,浮点等类型提示。
有些类的方法需要传入的参数为所期望的对象类型,可以用下面的方法达到强制实施此替则。
要达到类型提示,只要在方法的对象型参数前加一个已存在的类的名称,如:
functionfunname(OtherClassName$otherclassINSName,$c….),注意,OtherClassName必须是存在的类。
如下:
classem{ var$k=56;}
classtest{
function__construct()
{ echo$this->addab(newem(),2); }
functionaddab(em$j,$c) //这个方法,即可以在内部调用,也可以在外部调用。
只要作用域许可。
{ return$j->k+$c;}
}
$a=newtest();
$b=newem();
echo$a->addab($b,2);//或$a->addab(newem(),2);
十一、类的管理:
1、instanceof关键字:
用于分析一个对象是否是某一个类的实例或子类或是实现了某个特定的接口:
如下例,但要注意:
类名没有任何引号等定界符,否则会出错。
如test不能用’test’
classtest2{}
classtest{}
classtestChilernExtendstest{}
$a=newtest2();
$m=newtest();
$i=($minstanceoftest);
if($i)echo‘$m是类test的实例!
’;//getthisvalue
switch($ainstanceoftest){
casetrue:
echo‘YES
’;
break;
casefalse:
echo‘No
’; //getthisvalue
break;
}
$d=newtestChilern();
if($dinstanceoftest)echo‘$d是类test的子类!
’;//getthisvalue
2、确定类是否存在:
booleanclass_exists(stringclass_name):
class_exists(‘test’);
3、返回类名:
stringget_class(object),成功时返回实例的类名,失败则返回FALSE:
$a=newtest2();echoget_class($a); //返回test2
4、了解类的公用属性:
arrayget_class_vars(‘className’),返回关键数组:
包含所有定义的public属性名及其相应的值。
这个函数不能用实例名做变量
5、返回类方法:
get_class_methods(‘test’);//或:
get_class_methods($a);可用实例名做参数,返回包括构造函数在内的所有非私有方法。
6、print_r(get_declared_classes())了解当前PHP版本中所有的类名。
PHP5有149个。
7、get_object_vars($a)返回实例中所有公用的属性及其值的关联数组。
注意它和get_class_vars()的区别:
/*
(1)get_object_vars($a)是用实例名做参数,而get_class_vars(‘test’)是用类名做参数。
*
(2)get_object_vars($a)获得的属性值是实例运行后的值,而get_class_vars(‘test’)获得的属性值是类中的初始定义。
*(3)两者均返回关联数组,且均对未赋值的属性返回NULL的值。
如类test中有定义了public$q;则返回Array([v]=>5[q]=>),
*/
8、返回父类的名称:
get_parent_class($b);//或get_parent_class(‘test2′);返回test
9、确定接口是否存在:
booleaninterface_exists($stringinterface[,booleanautoload])
10、确定对象类型:
booleanis_a($obj,’className’),当$obj属于CLASSNAME类时,或属于其子类时,返回TRUE,如果$obj与class类型无关则返回FALSE。
如:
is_a($a,’test’)
11、确定是否是某类的子对象:
当$b是继承自TEST类时,返回TRUE,否则FALSE。
booleanis_subclass_of($b,’test’);
12、确定类或实例中,是否存在某方法。
method_exists($a,’getv’)//或用method_exists(‘test’,'getv’),此函数适用于非public定义的作用域的方法。
以上函数实例:
classtest{
public$v=2;
private$c=5;
function__construct(){
$this->v=5;
}
privatefunctiongetv(){
return$this->v;
}
}
classtest2extendstest{}
$a=newtest();
$b=newtest2();
print_r(get_class_methods(‘test’));//或:
print_r(get_class_methods($a));均返回:
Array([0]=>__construct[1]=>getv)
echo‘
’;
print_r(get_class_vars(‘test’));//返回:
Array([v]=>2),和上面不一样,不能用print_r(get_class_methods($a));
echo‘
’;
echoget_parent_class($b);//或get_parent_class(‘test2′);返回test
echo‘
’;
echois_a($b,’test’);//返回1
echo‘
’;
if(is_subclass_of(‘test2′,’test’))echo‘是子类!
’;//或(is_subclass_of($b,’test’)),返回1,当参数1为$a时则返回false,
echo‘
’;
echomethod_exists($a,’getv’)//或用method_exists(‘test’,'getv’)返回1,本函数也适用于用private等定义域的方法。
十一、自动加载类库文件:
当类多了以后,比如要在一个文件中载入3个类库文件:
a.class.php,b.class.php,c.class.php要用三个require_once(‘classes/a.class.php);
require_once(‘classes/b.class.php);
require_once(‘classes/c.class.php);
可以用PHP5自动加载的功能来处理:
在全局应用配置文件中,定义一个特殊的函数__autoload($class)函数(__autoload并不是一个类的方法,只是单独的函数,和类没有关系):
function__autoload($class){
require_once(“classes/$class)
}
该函数放哪没有关系,在创建类实例时,也不必去调用这个autoload函数。
PHP会自动完成。
但务必注意一点:
“在调用页面上创建实例所使用的类名称”、和“被调用的文件名”、以及“该文件中的类的名称”3个必须是一样的。
这样就不需要去调用__autoload();如果不一样则必须单独调用__autoload(‘c’);并给它一个文件名前缀。
如:
c.class.php文件的代码是:
php
classc{
public$m=7;
}
?
>这里代码的类名称是c,而文件名也是c,
现在要在index.php调用:
php
function__autoload($class){
require_once“$class.class.php”;
}
$m=newc();//创建实例调用的类也是c
echo$m->m;
?
>
此时PHP会自动调用根目录下的c.class.php中的类C。
但如果c.class.php中的代码是:
php
classmm{
public$m=7;
}
?
>
而调用页index.php代码是:
php
function__autoload($class){
require_once“$class.class.php”;
}
#__autoload(‘c’);//如果不加这一行就会出错。
$m=newmm();
echo$m->m;
?
>
会出错,提示找不到mm.class.php文件。
这时可以加一行__autoload(‘c’);但这样就达不到简化代码的目的。
类的家族化扩展:
类的高级功能:
一、对象克隆:
当克隆一个对象的实例时,其属性初始值继承了被克隆对象的当前值。
classtest