PHP面向对象之魔术方法

魔术方法

构造函数

  • 引言
    • __construct() 构造方法
    • __destruct() 析构方法
    • __clone() 克隆方法

对象用作字符串 函数

  • __tostring()

    • 将对象当成字符串使用的时候自动调用
  • __invoke()

    • 将对象当成函数使用的时候自动调用
<?php
class Student {
	//把对象当成字符串使用的时候自动执行
	public function __tostring() {
		return '这是一个对象,不是字符串<br>';
	}
	//把对象当成函数使用的时候自动执行
	public function __invoke() {
		echo '这是一个对象,不是函数<br>';
	}
}
$stu= new Student;
//当成字符串使用
echo $stu.'<br>';	
echo substr($stu, 0, 18).'<br>';
echo '<hr>';
//当成函数使用
$stu();		
?>

私有属性的读写

  • __set($k,$v)

    • 给无法访问的属性赋值的时候自动执行
  • __get($k)

    • 获取无法访问的属性值的时候自动调用
<?php
class Student {
	private $name;
	private $sex;
	private $age;
	//给无法访问的属性赋值的时候自动执行
	public function __set($k,$v) {
		$this->$k=$v;
	}
	//获取无法访问的属性值的时候自动调用
	public function __get($k) {
		return $this->$k;
	}
}
$stu= new Student;
//给私有属性赋值
$stu->name= 'Jerry';
$stu->sex='男';
$stu->age=29;
//获取私有属性的值
echo $stu->name.'<br>';
echo $stu->sex.'<br>';
echo $stu->age.'<br>';
?>
# 应用:设置读写属性
<?php
class Student {
	private $name;			//读写属性
	private $add='中国';	//只读属性
	private $age;			//只写属性
	
	public function __set($k,$v) {
		if(in_array($k,array('name','age')))
			$this->$k=$v;
		else
			echo "{$k}属性是只读属性<br>";
	}
	public function __get($k) {
		if(in_array($k,array('name','add')))
			return $this->$k;
		else
			echo "{$k}是只写属性<br>";
	}
}
//测试
$stu=new Student;
$stu->name='Sunny';
$stu->age=29;
echo '姓名:'.$stu->name,'<br>';
echo '地址:'.$stu->add,'<br>';
?>

判断私有属性的读取与销毁

  • __isset($k)

    • 判断无法访问的属性是否存在自动调用
  • __unset($k)

    • 销毁无法访问的属性的时候自动执行
<?php
class Student {
	private $name;
	private $sex;
	private $age;
	//判断无法访问的属性是否存在自动调用
	public function __isset($k) {
		return isset($this->$k);
	}
	//销毁无法访问的属性的时候自动执行
	public function __unset($k) {
		unset($this->$k);
	}
}
$stu= new Student;
//判断私有属性是否存在自动调用
var_dump(isset($stu->name));
//销毁私有属性
unset($stu->age);
print_r($stu);
?>

私有方法不存在自动执行

  • __call()

    • 调用无法访问的方法时自动执行
  • __callstatic()

    • 调用无法访问的静态方法时自动执行
<?php
class Student {
	/**
	*作用:调用无法访问的方法时自动执行
	*@param $fn_name string 方法名
	*@param $fn_args array 参数数组
	*/
	public function __call($fn_name,$fn_args) {
		echo "{$fn_name}不存在<br>";
	}
	//调用无法访问的静态方法时自动执行
	public static function __callstatic($fn_name,$fn_args) {
		echo "{$fn_name}静态方法不存在<br>";	
	}
}
//测试
$stu= new Student;
$stu->show(10,20);
Student::show();
?>
# 实现“过载”动作
<?php
class Magic { 
	function __call($name,$arguments){ 
		if($name=='foo'){ 
			if(is_int($arguments[0])) {
				$this->foo_for_int($arguments[0]); 
			}
			if(is_string($arguments[0])){
				$this->foo_for_string($arguments[0]); 
			}
		} 
	}   
	private function foo_for_int($x) { 
		print("oh an int!<br>"); 
	}   
	private function foo_for_string($x) { 
		print("oh a string!<br>"); 
	} 
} 
$x = new Magic(); 
$x->foo(3); 
$x->foo("3"); 
?>
<?php
abstract class Obj { 
	protected $property = array(); 
	abstract protected function show(); 
	public function __call($name,$value){ 
		if(preg_match("/^set([a-z][a-z0-9]+)$/i",$name,$array)){ 
			$this->property[$array[1]] = $value[0]; 
			return; 
		}elseif(preg_match("/^get([a-z][a-z0-9]+)$/i",$name,$array)){
			return $this->property[$array[1]]; 
		}else{ 
			exit("<br>Bad function name {$name} "); 
		} 
	} 
} 
class User extends Obj{ 
	public function show(){ 
		print ("Username: ".$this->property['Username']."<br>"); 
		//print ("Username: ".$this->getUsername().";"); 
		print ("Sex: ".$this->property['Sex']."<br>"); 
		print ("Age: ".$this->property['Age']."<br>"); 
	} 
} 
class Car extends Obj{ 
	public function show(){ 
		print ("Model: ".$this->property['Model']."<br>"); 
		print ("Sum: ".$this->property['Number'] * $this ->property['Price']."<br>"); 
	} 
} 
$user = new User; 
$user ->setUsername("Anny"); 
$user ->setSex("girl"); 
$user ->setAge(20); 
$user ->show(); 
print("<hr>"); 
$car = new Car; 
$car ->setModel("BW600"); 
$car ->setNumber(5); 
$car ->setPrice(40000); 
$car ->show(); 
?>

序列化函数

  • __sleep()

    • 当序列化的时候自动调用
  • __wakeup()

    • 当反序列化的时候自动调用
<?php
class Student {
	private $name;
	private $sex;
	private $add='中国';
	public function __construct($name,$sex) {
		$this->name=$name;
		$this->sex=$sex;
	}
	/**
	*序列化的时候自动调用
	*@return array 序列化的属性名
	*/
	public function __sleep() {
		return array('name','sex');
	}
	//反序列化的时候自动调用
	public function __wakeup() {
		$this->type='学生';
	}
}
//测试
$stu= new Student('Sunny','boy');
$str= serialize($stu);	    //序列化
$stu= unserialize($str);	//反序列化
print_r($stu);
?>
原文地址:https://www.cnblogs.com/SharkJiao/p/14120868.html