• 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);
    ?>
    
  • 相关阅读:
    Java集合类
    打开Eclipse报错
    FusionWidgets之AngularGauge图
    OLAP 大表和小表并行hash join
    分页SQL模板
    全表扫描分页
    Java中的a++和++a的区别
    JAVA中线程同步方法
    final、finally和finalize的区别
    HashMap和Hashtable的异同点
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/14120868.html
Copyright © 2020-2023  润新知