面向对象魔术方法及类的自动加载

一  __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();
原文地址:https://www.cnblogs.com/wfc139/p/9152231.html