本文目录:
访问修饰限定符
构造方法
析构方法
静态成员
类常量
单例模式
final关键字
魔术方法
抽象类
接口
面向对象是一种符合人类思维习惯的编程思想,PHP作为一种流行的编程语言,同样支持面向对象编程。
在PHP中,类名称不区分大小写,但是建议采用首字母大写的驼峰式命名
访问修饰限定符
在php中,提供了3个访问修饰符public、protected和private,它们可以对类中成员的访问做出一些限制。
public:公有修饰符,类内和类外的成员都没有访问限制。
如果类的成员没有指定访问修饰符,则默认为public。
protected:保护成员修饰符,类外的代码不能访问,类内和该类的子类可以对其进行访问、读写。
private:私有修饰符,对类内的成员可见并且没有访问限制,但在类的外部和该类的子类中不允许访问。
构造方法
在PHP中,__construct()被称为构造方法。
类会在每次创建新对象时先调用此方法,因此该方法适合在使用对象之前做一些初始化工作。
该方法和析构方法都被称为魔术方法,在ctf的php代码审计题中经常出现。
在PHP早期的版本中,与类同名的方法也被视为构造方法。当一个类中同时存在这两种构造方法时,PHP会优先选择__construct。
在 PHP7 中已不再支持与类同名的构造方法,只支持__construct。
析构方法
__destruct()被称为析构方法,与构造方法相对,是在一个对象被销毁时被自动调用的方法。
析构方法的作用是在销毁一个对象之前,执行一些操作或完成一些功能,如关闭文件释放结果集等。
静态成员
PHP中,类的静态成员同样分为属性和方法,与一般成员的声明语法类似,唯一的区别是需要使用 static关键字 将其声明为静态成员。
静态成员属于类本身,不属于类的对象。
定义静态成员的语法格式如下:
//定义静态属性:
public static $name;
//定义静态方法:
public static function call(){}
访问静态成员和访问普通成员也有一定区别,访问静态成员的示例代码如下:
class tool{
public static $arr='静态属性';
public static function getStatic(){
return tool::$arr; //类内访问静态属性方式一,使用类名+"::"+静态属性
return self::$arr; //类内访问静态属性方式二,使用self+"::"+静态属性
}
}
//类外访问静态属性
echo tool::$arr;
//类外访问静态方法
tool::getStatic();
上述代码中的self表示当前类,是在类内调用静态成员的方式。而 类名 在类内和类外都可以调用。:: 被称为静态访问符,访问静态成员都需要通过这个操作符来完成。
在PHP5.3以后,又提供了一个新的方式来访问静态成员:static::静态成员
类名、self、static访问静态成员的区别:
使用 类名,可以在类的内部或类的外部访问本类的静态成员。
使用 slef,仅可以在类的内部访问本类的静态成员。
使用 static,仅可以在类的内部访问本类和其父类的静态成员。
类常量
在PHP中,类内除了可以定义成员属性、成员方法、静态成员属性、静态成员方法外,还可以定义类常量。定义类常量需要使用const关键字,语法格式为:
const 类常量名='常量值';
类常量名定义规则与变量名一致,但在开发习惯上通常把类常量名以大写字母表示。
访问类常量与静态属性一致,使用"::"符号,该符号也被叫做范围解析符。
定义类常量的意义在于,可以通过定义有意义的类常量名来表示无意义的数据,方便开发人员阅读。
单例模式
有些类 (如数据库操作类) 只有一个对象 (实例) 就能完成所有任务,因此站在设计程序的角度,应该限制该类实例化多个对象,做到有且只有一个对象,从而实现节约资源的目的。这样的设计模式,就成为单例模式。
实现单例模式的三个步骤:
私有化构造方法,防止在类的外部通过new构造对象
私有化 __clone方法,防止通过__clone关键字复制对象
通过静态方法去获得实例
final关键字
如果不希望某个类被继承,只能被实例化,可以通过final关键字来声明。示例代码:
final class child extends parent{
//本类不能被继承,只能被实例化
}
当一个类被继承时,所包含的final方法不能被子类重写。这样可以限制要求在子类中一定存在某个功能的方法。示例代码:
class parent{
final protected function call(){}
}
魔术方法
PHP中有很多以两个下划线开头的方法,如__construct()、__destruct()、__autoload()、__get()、__set()等,这些方法被称为魔术方法。
魔术方法的特点是不需要手动调用,在某一时刻会自动执行,为程序的开发带来了极大的便利。
抽象类
抽象类不能直接被实例化,必须先继承该抽象类,然后再实例化子类。抽象类中至少要包含一个抽象方法。如果类方法被声明为抽象的,那么其中就不能包括具体的功能实现。继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法。另外,这些方法的访问权限必须和抽象类中一样或者更为宽松。例如抽象类的某个抽象方法被声明为protected,那么子类中实现的方法就应该声明为protected或者public,不能定义为private。
接口
接口的定义:interface 接口名{}
//定义usb接口
interface usb{
public function connect(); //连接
public function transfer(); //传输数据
public function disconnect(); //断开连接
}
接口的定义就像定义一个标准的类一样,但其中定义的所有方法都是空的。接口中定义的所有方法都必须是public,这是接口的特性。要实现一个接口,可以使用implements操作符。类中必须实现接口中定义的所有方法,否则会报fatal错误。如果要实现多个接口,可以使用逗号分隔接口名称,如:
//mp3类实现usb接口和player接口
class mp3 implements usb,player{
//需要实现usb和player接口的所有方法
}