美文网首页
PHP进阶知识点

PHP进阶知识点

作者: LaputCat | 来源:发表于2019-10-09 14:07 被阅读0次

    慕课网学习笔记

    类和对象

    类是面向对象程序设计的基本概念,通俗的理解类就是对现实中某一个种类的东西的抽象
    比如汽车可以抽象为一个类,汽车拥有名字、轮胎、速度、重量等属性,可以有换挡、前进、后退等操作方法。
    对象通过new关键字进行实例化类

    class Car {
    }
    $car  = new car();实例化
    
    类的属性

    在类中定义的变量称之为属性,通常属性跟数据库中的字段有一定的关联,因此也可以称作“字段”。
    属性声明是由关键字 public,protected 或者 private 开头,后面跟一个普通的变量声明来组成。属性的变量可以设置初始化的默认值,默认值必须是常量

    class Car {
        //定义公共属性
        public $name = '汽车';
    
        //定义受保护的属性
        protected $corlor = '白色';
    
        //定义私有属性
        private $price = '100000';
    }
    1.默认都为public,外部可以访问。一般通过->对象操作符来访问对象的属性或者方法,
    对于静态属性则使用::双冒号进行访问。
    当在类成员方法内部调用的时候,可以使用$this伪变量调用当前对象的属性。
    2.受保护的属性与私有属性不允许外部调用,在类的成员方法内部是可以调用的
    
    类的方法

    方法就是在类中的function
    在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法。
    同属性一样,类的方法也具有public,protected 以及 private 的访问控制

    class Car {
        public function getName() {
            return '汽车';
        }
    ​}
    $car = new Car();
    echo $car->getName();
    
    使用关键字static修饰的,称之为静态方法
    静态方法不需要实例化对象,可以通过类名直接调用,操作符为双冒号::
    class Car {
        public static function getName() {
            return '汽车';
        }
    ​}
    echo Car::getName(); //结果为“汽车”
    
    类的方法之构造函数和析构函数
    构造函数:实例化的时候 会自动调用构造函数__construct
    class Car {
       public  function __construct() {
           print "构造函数被调用\n";
       }
    }
    $car = new Car(); 
    
    调用继承父类的构造函数使用parent::__construct()显式的调用。
    class Truck extends Car {
       function __construct() {
           print "子类构造函数被调用\n";
           parent::__construct();
       }
    }
    $car = new Truck();
    
    析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。
    class Car {
       function __construct() {
           print "构造函数被调用 \n";
       }
       function __destruct() {
           print "析构函数被调用 \n";
       }
    }
    $car = new Car(); //实例化时会调用构造函数
    echo '使用后,准备销毁car对象 \n';
    unset($car); //销毁时会调用析构函数
    
    类的关键字static

    静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用。静态属性不允许对象使用->操作符调用。

    class Car {
        private static $speed = 10;
        
        public static function getSpeed() {
            return self::$speed;
        }
    }
    echo Car::getSpeed();  //调用静态方法
    
    静态方法中,$this伪变量不允许使用。可以使用self,parent,static在内部调用静态方法与属性。
    
    访问控制

    访问控制通过关键字public,protected和private来实现。
    1.被定义为 公有的类 成员可以在任何地方被访问。
    2.被定义为 受保护的类 成员则可以被其自身以及其子类和父类访问。
    3.被定义为 私有的类 成员则只能被其定义所在的类访问。

    重载

    PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的。

    • 属性重载:
    通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。
    class Car {
        private $ary = array();
        
        public function __set($key, $val) {
            $this->ary[$key] = $val;
        }
        
        public function __get($key) {
            if (isset($this->ary[$key])) {
                return $this->ary[$key];
            }
            return null;
        }
        
        public function __isset($key) {
            if (isset($this->ary[$key])) {
                return true;
            }
            return false;
        }
        
        public function __unset($key) {
            unset($this->ary[$key]);
        }
    }
    $car = new Car();
    $car->name = '汽车';  //name属性动态创建并赋值
    echo $car->name; //汽车
    
    • 方法重载:
    通过__call来实现,当调用不存在的方法的时候,将会转为参数调用__call方法,当调用不存在的静态方法时会使用__callStatic重载。
    class Car {
        public $speed = 0;
        
        public function __call($name, $args) {
            if ($name == 'speedUp') {
                $this->speed += 10;
            }
        }
    }
    $car = new Car();
    $car->speedUp(); //调用不存在的方法会使用重载
    echo $car->speed; //10
    
    对象高级特性
    • 对象比较
    1.当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,
    2.当需要判断两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断。
    class Car {
    }
    $a = new Car();
    $b = new Car();
    if ($a == $b) echo '==';   //true
    if ($a === $b) echo '==='; //false
    
    • 对象复制
    关键字clone来复制一个对象,这时__clone方法会被调用,通过这个魔术方法来设置属性的值。
    class Car {
        public $name = 'car';
        
        public function __clone() {
            $obj = new Car();
            $obj->name = $this->name;
        }
    }
    $a = new Car();
    $a->name = 'new car';
    $b = clone $a;
    var_dump($b);
    
    object(Car)#2 (1) {
      ["name"]=>
      string(7) "new car"
    }
    
    • 对象序列化
    serialize方法将对象序列化为字符串,用于存储或者传递数据
    通过unserialize将字符串反序列化成对象进行使用
    class Car {
        public $name = 'car';
    }
    $a = new Car();
    $str = serialize($a); //对象序列化成字符串
    echo $str.'<br>';
    $b = unserialize($str); //反序列化为对象
    var_dump($b);
    
    异常处理
    基本语法
            try{
                //可能出现错误或异常的代码
                //catch表示捕获,Exception是php已定义好的异常类
            } catch(Exception $e){
                //对异常处理,方法:
                    //1、自己处理
                    //2、不处理,将其再次抛出
            }
    既然抛出异常会中断程序执行,那么为什么还需要使用异常处理?
    异常抛出被用于在遇到未知错误,或者不符合预先设定的条件时,通知客户程序,以便进行其他相关处理,不至于使程序直接报错中断。
    
    异常处理类

    Exception是所有异常处理的基类。
    Exception具有几个基本属性与方法:

    • message 异常消息内容
    • code 异常代码
    • file 抛出异常的文件名
    • line 抛出异常在该文件的行数
      常用方法:
      getTrace 获取异常追踪信息
      getTraceAsString 获取异常追踪信息的字符串
      getMessage 获取出错信息
    只有在极端情况或者非常重要的情况下,才会抛出异常
    一般的异常处理流程代码为:
    try {
        throw new Exception('wrong');
    } catch(Exception $ex) {
        $msg = 'Error:'.$ex->getMessage()."\n";
        $msg.= $ex->getTraceAsString()."\n";
        $msg.= '异常行号:'.$ex->getLine()."\n";
        $msg.= '所在文件:'.$ex->getFile()."\n";
        //将异常信息记录到日志中
         PHP异常处理之   file_put_contents('error.log', $msg);
    }
    echo '异常处理后,继续执行其他代码';
    
    正则表达式
    正则匹配模式
    PCRE库函数
    正则匹配模式使用分隔符与元字符组成,分隔符可以是非数字、非反斜线、非空格的任意字符。
    分隔符是正斜线(/)、hash符号(#) 、以及取反符号(~)
    
    /foo bar/
    #^[^0-9]$#
    ~php~
    
    元字符
    常用元字符
    
    \ 一般用于转义字符
    ^ 断言目标的开始位置(或在多行模式下是行首)
    $ 断言目标的结束位置(或在多行模式下是行尾)
    . 匹配除换行符外的任何字符(默认)
    [ 开始字符类定义
    ] 结束字符类定义
    | 开始一个可选分支
    ( 子组的开始标记
    ) 子组的结束标记
    ? 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词)
    * 量词,0 次或多次匹配
    + 量词,1 次或多次匹配
    { 自定义量词开始标记
    } 自定义量词结束标记
    

    PHP元字符详解

    以下来自PHP5权威编程

    静态属性
    属于类本身而非是类的实例
    相当于是存储在类的全局变量,可以通过类在任何地方访问
    由关键字 static定义
    访问:
    类名::定义静态名
    Person::  $name
    
    静态方法
    访问:class_name::method
    
    常量
    与静态成员类似 属于类的本身不是属于类的实例
    访问:self::常量名[规范大写]  
    
    self:: parent::
    self 指向当前的类 用于访问静态属性、方法、常量
    parent 指向父类 用于调用父类的构造函数和方法
    
    instance of 逻辑二元运算符
    用于确定一个 PHP 变量是否属于某一类 [class]
    _CLASS_  用于存储当前类名
    
    判读是否是属于某一类
    Abstract 抽象方法和抽象类

    抽象类不能够被实例化/初始化,但是可以依靠具体类的继承来实现。
    继承的子类必须实现了抽象类中的所有抽象方法,否则会报错
    如果子类没有全部实现抽象类中的所有抽象方法,那么该子类也是一个抽象类,必须在 class 前面加上 abstract 关键字,并且不能被实例化

    定义:
    
     class 前加了 abstract 关键字且存在抽象方法
    (在类方法 function 关键字前加了 abstract 关键字)的类。
    
    abstract class A
    {
        /** 抽象类中可以定义变量 */
        protected $value1 = 0;
        private $value2 = 1;
        public $value3 = 2;
        /** 也可以定义非抽象方法 */
        public function my_print()
        {
            echo "hello,world/n";
        }
        /**
         * 大多数情况下,抽象类至少含有一个抽象方法。
            抽象方法用abstract关键字声明,其中不能有具体内容。
         * 可以像声明普通类方法那样声明抽象方法,
            但是要以分号而不是方法体结束。
        也就是说抽象方法在抽象类中不能被实现,也就是没有函数体“{some codes}”。
         */
        abstract protected function abstract_func1();
        abstract protected function abstract_func2();
    }
    //部分继承抽象类A,且不能实例化
    abstract class B extends A
    {
        public function abstract_func1()
        {
           echo "implement the abstract_func1 in class A/n";
        }
        /** 这么写在zend studio 8中会报错
        //abstract protected function abstract_func2();
              遵循以下规则:
              B类的成员访问控制不能比A类严格
              A->public        B->public
              A->protected  B->public、protected 
              A不能定义为 private
    ( Fatal error : Abstract function A::abstract_func() cannot be declared private )
        */
    }
    class C extends B
    {
        public function abstract_func2()
        {
           echo "implement the abstract_func2 in class A/n";
        }
    }
    
    interface 接口

    参考文章:
    interface abstract 不同点和相同点参考文章

    interface 是完全抽象的,只能声明方法,而且只能声明 public 的方法,不能声明 private 及 protected 的方法,不能定义方法体,也不能声明实例变量 。然而, interface 却可以声明常量变量

    interface iA
    {
        const AVAR=3;
        public function iAfunc1();
        public function iAfunc2();
    }
    echo iA:: AVAR;
    
    任何实现接口的类都要实现接口中所定义的所有方法,否则要声明为abstract类
    class E implements iA
    {
        public function iAfunc1(){echo "in iAfunc1";}
        public function iAfunc2(){echo "in iAfunc2";}
    }
    
    abstract class E implements iA{}
    类可以在声明中使用 implements 关键字来实现某个接口
    
    interface iB
    {
        public function iBfunc1();
        public function iBfunc2();
    }
    class D extends A implements iA,iB
    {
        public function abstract_func1()
        {
           echo "implement the abstract_func1 in class A/n";
        }
        public function abstract_func2()
        {
           echo "implement the abstract_func2 in class A/n";
        }
        public function iAfunc1(){echo "in iAfunc1";}
        public function iAfunc2(){echo "in iAfunc2";}
        public function iBfunc1(){echo "in iBfunc1";}
        public function iBfunc2(){echo "in iBfunc2";}
    }
     类可以同时继承一个父类和实现任意多个接口
    class D extends B implements iA,iB
    {
        public function abstract_func1()
        {
           parent::abstract_func1();
           echo "override the abstract_func1 in class A/n";
        }
        public function abstract_func2()
        {
           echo "implement the abstract_func2 in class A/n";
        }
        public function iAfunc1(){echo "in iAfunc1";}
        public function iAfunc2(){echo "in iAfunc2";}
        public function iBfunc1(){echo "in iBfunc1";}
        public function iBfunc2(){echo "in iBfunc2";}
    }
    
    final方法和类
     final方法:确保一个方法不被继承类改写
    final类:确保一个类不被继承
    

    相关文章

      网友评论

          本文标题:PHP进阶知识点

          本文链接:https://www.haomeiwen.com/subject/fvmfrctx.html