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


    一  __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();
    
  • 相关阅读:
    【转】git教程
    Ubuntu下编译运行Kamailio
    windows下编译FreeSwitch
    自己常用的wireshark过滤条件
    CSRF 漏洞原理详解及防御方法
    Sql 注入详解:宽字节注入+二次注入
    Kali下Ettercap 使用教程+DNS欺骗攻击
    Sql注入的分类:数字型+字符型
    Windows Server 2012 R2 配置FTP服务器
    Kali Linux 初始化配置:Apache2 /SSH /FTP
  • 原文地址:https://www.cnblogs.com/wfc139/p/9152231.html
Copyright © 2020-2023  润新知