面向对象魔术方法及类的自动加载
一 __get和__set
1.当去使用不可访问的属性时,系统就会调用__get方法 不可访问属性:该属性不存在 直接访问protected或private属性
2.当去给不可访问属性赋值时,会调用__set方法
<?php
echo '<meta charset="utf-8">';
class Monkey{
public $name;
protected $food;
public function __construct($name,$food){
$this->name = $name;
$this->food = $food;
}
//魔术方法的名字是固定的
//$pro_name形参 表示属性名
public function __get($pro_name){
//做一个判断 property_exists判断对象或类中是否有该属性
if(property_exists($this,$pro_name)){
return $this->$pro_name;
}else{
return '没有该属性,无法返回';
}
}
//形式参数 属性名$pro_name 属性值$pro_val
public function __set($pro_name,$pro_val){
//做一个判断 property_exists判断对象或类中是否有该属性
if(property_exists($this,$pro_name)){
$this->$pro_name = $pro_val;
}else{
echo '属性不存在,无法赋值';
}
}
}
$Monkey1 = new Monkey('悟空','桃子');
//触发__get魔术方法
echo $Monkey1->name;
echo $Monkey1->food;
//触发__set魔术方法
$Monkey1->name = '孙悟空';
$Monkey1->food = '香蕉';
echo $Monkey1->name;
echo $Monkey1->food;
二,__isset和__unset
1.当对不可访问的属性,进行了isset($对象名->属性名),empty($对象名->属性名),__isset函数就会被系统调用
2.当对不可访问的属性,进行了unset($对象名->属性名),__unset函数就会被系统调用
<?php echo '<meta charset="utf-8">'; class Cat{ public $name; private $food; public function __construct($name,$food){ $this->name = $name; $this->food = $food; } public function __isset($pro_name){ if(property_exists($this,$pro_name)){ return true; }else{ return false; } } public function __unset($pro_name){ if(property_exists($this,$pro_name)){ unset($this->$pro_name); }else{ echo '属性不存在,无法删除'; } } } $cat1 = new Cat('波斯猫','<。)#)))≦'); //判断name 属性是否存在 if(isset($cat1->name)){ echo '<br>name 属性是存在的'; }else{ echo '<br>name 属性是不存在的'; } //判断food 属性是否存在 //此时food是私有属性 因此会调用__isset方法 if(isset($cat1->food)){ echo '<br>food 属性是存在的'; }else{ echo '<br>food 属性是不存在的'; } //如果销毁的成员属性,是protected或者private的,就不能直接unset //此时food是私有属性 因此会调用__unset方法 unset($cat1->name); var_dump($cat1); echo '<br>-------------------'; unset($cat1->food); var_dump($cat1);
三.__toString
当输出一个对象时,就会触发该函数
1.__toString没有形参
2.__toString要求返回一个字符串
3.当我们在项目开发时,需要找bug时,可以通过他输出对象信息
<?php echo '<meta charset="utf-8">'; class Cat{ public $name; private $food; public function __construct($name,$food){ $this->name = $name; $this->food = $food; } public function __toString(){ return '名字:'.$this->name.'食物:'.$this->food; } } $cat1 = new Cat('波斯猫','<。)#)))≦'); echo $cat1;
property_exists(对象名,属性):
1.先判断该对象是否有这个属性,如果有则返回真
2.如果该对象没有此属性,则继续判断该对象对应的类是否定义过这个属性,如果类定义过,就返回真
四,__clone
当将一个对象完全的复制一份,保证两个对象的属性和属性值一样,但他们的数据空间独立,则可以使用对象克隆
1.克隆一个对象时,克隆方法里面可以修改属性的值
2.当不想被克隆时,将克隆方法private 例如:单例模式时
<?php echo '<meta charset="utf-8">'; class Sheep{ public $name; public $food; public function __construct($name,$food){ $this->name = $name; $this->food = $food; } public function __clone(){ //克隆一个对象时,克隆方法里面可以修改属性的值 $this->food = '树叶'; } } $sheep1 = new Sheep('羊','草');
//克隆一个对象 $sheep2 = clone $sheep1; var_dump($sheep1->food); var_dump($sheep2->food);
五.__call
1.当调用了一个不可访问的成员方法(成员方法不存在,成员方法为protected或private)时,__call()方法就会被调用
<?php
echo '<meta charset="utf-8">';
class number{
public $num1;
public $num2;
protected function numAnd($num1,$num2){
return $num1+$num2;
}
/*
两个参数:方法名:$method_name 参数:$parameters是个数组
在本例中的方法名是numAnd 参数是:10,20
*/
public function __call($method_name,$parameters){
//method_exists判断该类中有没有这个方法
if(method_exists($this,$method_name)){
return $this->$method_name($parameters[0],$parameters[1]);
}else{
echo '没有你调用的函数';
}
}
}
$num3 = new number();
echo $num3->numAnd(10,20);
六,__autoload类的自动加载
1.当使用一个未定义的类时,就会触发__autoload这个函数
2.function __autoload($class_name){} 其中class_name是类名
例如:
但是,如果一个php中引入多个类时,这样做显然就会麻烦了,不可能一直用require或include引入,所以可以将这些类用类名当键,文件名当值组成一个数组,放到一个php文件中,当用时将次php文件引入即可;
例如:Cat.class.php
<?php class Cat{ public $name; public $age; public function cry(){ echo '喵'; } }
Dog class.php
<?php class Dog{ public $name; public $age; public function cry(){ echo '汪'; } }
common.php
<?php $class_arr = array(
//类名为键 文件路径为值组成的数组 'Dog'=>'./Dog.class.php', 'Cat'=>'./Cat.class.php' );
使用:
<?php echo '<meta charset="utf-8">'; //引入放类数组的php文件 include './common.php'; function __autoload($class_name){ //对common.php文件中的数组$class_arr进行一下声明 global $class_arr; //require或include数组元素 require $class_arr[$class_name]; } $dog = new Dog(); $cat = new Cat(); $dog->cry(); $cat->cry();