类与对象
PHP5起完全重写了对象模型。
类的定义
class 类名{ // 声明属性(可声明常量或变量)
const 常量名 = 值;
public $变量名 = 值; // 声明方法 public function 方法名(){ // 方法体 } }
类名 :不能使用PHP保留字。必须以字母或下划线开头,后跟若干字母、下划线或数字。
$this 是一个到主叫对象的引用
创建对象(实例) - 前提:类需提前定义好
在类外部创建
$对象名 = new 类名();
在类内部创建
$对象名 = new self; $对象名 = new parent;
访问属性与方法
$对象名->属性名; $对象名->方法名();
类的继承 - 只支持单继承
class 子类名称 extends 父类名称{}
子类会继承父类的公有及受保护的属性和方法。
被继承的属性和方法可以通过同样的名称重新声明来覆盖。
覆盖方法时,参数必须保持一致。(构造方法除外)
可以通过parent::来访问被覆盖的属性或方法。
如果父类定义方法时使用了final,则该方法不可覆盖。
获取类的完全限定名称 - 对使用了命名空间的类很有用
php 5.5起
类名::class
类的属性
// 定义 访问修饰符 $属性名 = 常数; // 访问修饰符:public/protected/private 常数是指PHP在编译阶段就可以得到的值,而不依赖运行时的信息才能求值 // 类方法中的访问方式 $this->属性名; // 非静态属性 self::$属性名; // 静态属性
类的常量
// 定义 const 常量名 = 值; // 类方法中访问 self::常量名;
类的自动加载
php5中,spl_autoload_register()函数可以注册任意数量的自动加载器,当使用尚未被绑定的类或接口时自动去加载。
构造方法 - 每次创建对象时先调用此方法,适合在使用对象前做一些初始化工作
class 类名{ function __construct(){
parent::__construct(); // 调用父类构造方法
} }
析构方法 - 在某个对象所有引用被删除或当对象被显式销毁时执行
class 类名{ function __destruct(){ parent::__destruct(); // 调用父类析构方法 } }
访问控制 - 针对属性和方法
public 公有 ,在任何地方都可以访问
protected 受保护,在类内部、子类、父类中可访问。
private 私有,只能在自身类内部访问。
范围解析操作符 ::
可用于访问静态成员、类常量、调用父类中被覆盖的方法。
static - 声明类属性或方法为静态,就可以不实例化而直接访问
静态属性不能通过一个类已实例化的对象来访问,但是静态方法可以。
$this不能在静态方法中使用。
静态属性不能使用 -> 操作符访问
抽象类 abstract - 不能被实例化
任何一个类,如果类中只要有一个方法被声明为抽象的,那么这个类就必须声明为抽象类。
继承一个抽象类,子类必须继承父类中所有抽象方法。(此外,这些方法的访问控制必须和父类一样或更为宽松)
抽象方法只有方法的声明,没有方法体。
接口 interface
接口中的所有方法必须是公有的 public ,且只有方法的声明,没有方法体。
类可以通过implements实现多个接口,接口之间用逗号分隔。
类必须实现接口中定义的所有方法。
接口之间也可以有继承关系,通过extends关键实现继承。
接口中可以定义常量,但不能被子接口或子类所覆盖。
trait - 代码复用的一种机制
php5.4起
trait本身不能实例化
trait 名称{ // 属性、方法 }
class 类名{ use trait名称; // 多个trait可用逗号分隔 }
优先级:当前类的方法会覆盖trait的方法,trait的方法会覆盖被继承类中的方法。
冲突解决
<?php trait A { public function smallTalk() { echo 'a'; } } trait B { public function smallTalk() { echo 'b'; }
public function bigTalk(){
echo 'B';
} } class Talker { use A, B { B::smallTalk insteadof A; // 明确指定使用冲突方法中的哪一个
B::bigTalk as talk; // 为某个方法引入别名 也可以 B::bigTalk as protected; 来改变方法的访问控制
} }?>
trait中使用trait
trait 名称{ use trait名称; // 多个trait使用逗号分隔 }
匿名类 php7
new class{ }
重载
当调用当前环境下未定义或不可见的属性或方法时,重载方法(魔术方法)会被调用。
所有的重载方法都必须声明为public
属性重载
public __set ( string $name , mixed $value ) : void // 在给不可访问属性赋值时,__set() 会被调用 public __get ( string $name ) : mixed // 读取不可访问属性的值时,__get() 会被调用 public __isset ( string $name ) : bool // 当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用 public __unset ( string $name ) : void // 当对不可访问属性调用 unset() 时,__unset() 会被调用 // 属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。
方法重载
public __call ( string $name , array $arguments ) : mixed // 在对象中调用一个不可访问方法时,__call() 会被调用 public static __callStatic ( string $name , array $arguments ) : mixed // 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用
遍历对象
foreach($对象名 as $key=>$value){} // 遍历其可以访问的可见属性
其它方法:实现Iterator接口遍历对象 或 实现IteratorAggregate接口来实现遍历对象
魔术方法
__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep()
__wakeup()
__toString()
__invoke()
__set_state()
__clone()
__debugInfo()
public __toString ( void ) : string // 用于一个类被当成字符串时应怎样回应 public __invoke ([ $... ] ) : mixed // 当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用 public static __set_state ( array $properties ) : object // 自 PHP 5.1.0 起当调用 var_export() 导出类时,此静态 方法会被调用 public __debugInfo ( void ) : array
public __sleep ( void ) : array // serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。该方法常用于提交未提交的数据,或类似的清理操作 public __wakeup ( void ) : void // unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。
final 如果父类方法被声明为final,子类无法覆盖该方法。如果类被声明为final,则不能被继承。
对象复制
$copy_of_object = clone $object;
当对象复制后,PHP5会对对象所有的属生执行一个浅复制.所有的引用属性,仍会是一个指向原来变量的引用.
当复制完成后,如果定义了__clone()方法,则复制的对象中的__clone()方法会被调用.
对象比较
当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等
而如果使用全等运算符(===),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)。
类型结束
函数的参数可以指定必须为 对象/接口/数组/callable
后期静态绑定
php5.3
用于在继承范围内引用静态调用的类.
使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类:
static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。
对象与引用
$objA -> 标识符A -> 对象内容A
$objB = $objA;
$objB->标识符B->对象内容A (其中 标签符B=标识符A)
对象序列化
所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。
unserialize()函数能够重新把字符串变回php原来的值。为了能够unserialize()一个对象,这个对象的类必须已经定义过。
序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。
浙公网安备 33010602011771号