PHP进阶知识点

类和对象

类是面向对象程序设计的基本概念,通俗的理解类就是对现实中某一个种类的东西的抽象
比如汽车可以抽象为一个类,汽车拥有名字、轮胎、速度、重量等属性,可以有换挡、前进、后退等操作方法。
对象通过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类:确保一个类不被继承
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,082评论 1 32
  • 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?答:可以有多个类,但只能有一个publ...
    岳小川阅读 906评论 0 2
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,207评论 0 2
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,041评论 0 4
  • 中国分为两种人:南方人和北方人。 关于南北方的定义官方的说法是:中国南北方通常以秦岭淮河为界,即秦岭淮河以北为北方...
    槽值阅读 4,586评论 32 67