类的自动加载
由于面向对象三大思想之一便是封装,在很多文件中我们需引入别的类文件来实现相应操作,这就可能导致引入文件过大导致繁琐的逻辑思考。这就需要制定一个标准来动态引入某个类文件
标准:封装类文件时用类名.class.php作为文件名;自动引入文件做法如下:
使用__autoload魔术函数
原理:当“程序需要一个类”的时候,就会自动调用该函数:该函数需我们自己定义并在其中编程
程序需要类的情况:
- 创建对象
- 直接使用类名(操作静态属性或静态方法)
Require语句负责引入类文件,./library/表明该类文件所在的文件夹
使用spl_autoload_register函数
__autoload限定了程序需要类自动调用某特定函数以导入文件,那么此方法可以将任何函数当做__autoload使用,使用该方法时__autoload失去了自动调用的机制,需重新设置
语法如下:
Spl_autoload_register(“函数名1”);
Spl_autoload_register(“函数名2”);……
使用spl_autoload_register函数也能将__autoload放入此函数中
//使用spl_autoload_register时相当于__autoload失效了不会被自动调用,需放入spl_autoload_register中
对象的复制(克隆)clone
前面讲单例模式的时候就讲到了克隆,下面我们更深入的了解一下克隆
浅克隆
顾名思义:普通的克隆只能可能对象中的“非对象非资源”数据:
普通克隆能克隆对象中的属性和方法
可看出普通克隆不能克隆对象中的对象和资源,于是深克隆诞生了
深克隆
首先我们了解了克隆时系统会自动调用系统魔术方法__clone,当我们想克隆对象中的对象和资源时,我们只需在此魔术方法中再克隆一下其中的对象和资源
结果为:
对象遍历
像数组一样,对象也能使用foreach进行遍历,注意如下:
- 只能遍历属性,方法无法遍历
- 只能遍历满足访问权限的属性
在类外进行遍历:
可见,protect和private属性因为访问权限问题无法访问,如需全部访问则需在类中访问:
如需访问局部属性,只需限制即可:
PHP内置标准类:
某类如上,可见标准类即没有内容的类,那么我们如何使用呢?可直接用不存在的属性方法名赋值使用
将数据转换为对象
基本语法:(目标类型)数据
- 对象转换为对象:没有变化
- 数组转换为对象:数组的键名当做属性名,值为对应值;
- 数字下标对应属性不方便进行操作
- 通常适合纯字符下标的数组
- Null转换为对象:空对象;
结果为:
- 其他标量数据转换为对象,属性名为固定的“scalar”,值为该变量的值
类型约束
什么是类型约束?在强类型语言中,基本的一个特性就是固定类型的变量只能装相应类型的数据。比如:
Int n1 = 1; //int类型变量
Float f1; //float类型变量
Bool function getConcat(string s1, string s2){……} //两个形参必须为字符型,返回bool型数据
Php是弱类型语言,无需为变量指定类型且可以存储任何类型
在php新版本中,某些场合可针对某些特定类型进行语法约束。
场合:函数(方法)的形参变量
特定类型:对象类型(类名),接口类型(接口名),数组类型(array),函数类型(callable)
约束介绍:
- Function f1(类名 $p1){…} //要求该参数只能使用该类的对象
- Function f1(接口名 $p1){……} //该参数只能使用实现该接口的对象
- Function f1(array $p1){……} //该参数只能是数组
- Function f1(callable $p1){……} //要求该参数只能是一个函数或方法,此时称之为回调函数(方法)
同样代码对$p1加上类型约束
与类有关的魔术常量
__CLASS__:获取所在类的类名
__METHOD__:获取所在的方法名
Class A{
Function f1(){
Echo __CLASS__; //输出“A”
Echo __METHOD__; //输出“f1”
}
}
数据(变量)序列化/反序列化
什么是序列化?就是将一个变量的数据“转换为”字符串然后存储到文件中,相应反序列化就是将文件中的序列化的数据转换成原来相同类型的数据
一个重要的功能:保留场景及所包含的内容
序列化操作:
1,$str = serialize($变量); //通过serialize系统函数将变量数据转换为字符串然后存储到变量$str中
2,file_put_contents(“文本文件路径”, $str); //保存字符串到文件中
反序列化操作:
1,$str = file_get_contents(“文本文件路径”);将文件里的数据提取出来赋给变量
2,$var = unserialize($str); //通过unserialize反序列化系统函数将字符串转换为原来类型的值
其他魔术方法
__sleep()和__wakeup()
当对对象进行序列化和反序列化的时候,往往反序列化得到的对象无法完成一些正常操作,比如对一个进行连接数据库和执行sql语句的类对象进行反序列化我们会发现该对象没有连接数据库,这时候我们需单独在反序列时系统自动调用的函数中进行连接数据库。于是__sleep()和__wakeup()函数诞生了。
Sleep():当对一个对象进行“序列化操作时”,会自动调用类中的__sleep()方法
Wakeup():当对一个对象进行“反序列化”时,会自动调用类中的__wakeup()方法
注意:反序列化操作中,必须已经具备了对应的类的声明
__Sleep()方法中可以进行一些数据(资源)的清理工作并返回一个数组,该数组可以存储一些想要进行序列化的对象属性
__wakeup()方法中可以在进行反序列化操作中的时候进行某些有用的“数据恢复工作”,比如:连接数据库
反序列化:
__tostring()方法
当把一个对象当做“字符串”处理的时候,会自动调用该魔术方法,通过该方法,可以返回“合适”的字符串,也可以认为就是对象转换为字符串的结果
如果没有改方法,会出错,对象不能直接当字符串使用
添加魔术方法:
__invoke()方法
与上面__tostring方法类似,当对象当做“方法”使用的时候,会自动调用该魔术方法
比如:$v1 = $obj1(1, 2) //$obj1为一个对象
一些有关类和对象的系统函数和运算符
Class_exists:判断某个类是否存在(定义过)
Interface_exists():判断接口是否存在
Get_class():获取某个对象的“所属类名”
Get_parent_class:获取某个对象所属“父类”的类名
Get_class_methods():获取一个类的所有属性,返回一个索引数组
Get_class_vars():获取一个类的所有属性返回一个数组,下标为属性名,值为属性值
Get_declared_classes():获得所有说明过的类(含系统中的类)
Is_object():判断是否为对象
Get_object_vars():获得对象的所有属性,返回一个数组下标为属性名,值为属性值
运算符:
New:
Instanceof:判断一个对象是否是某个类的“实例”
两个特定语法场景的辨析:
对象向下传递特性:
当一个对象$o1调用一个实例方法f1,然后在该实例方法f1中又去“静态”调用另一个类的方法f2,则在f2中会自动获得方法f1中的那个$this对象
对比:
Static后期静态绑定特性:
注意:static::$p1中static代表的是调用该方法的那个类
面向对象3大思想特征介绍:
封装:
把数据“封闭”起来,面向对象的基本语法“类的定义形式”,可认为是最基本封装
但: 更严格的封装,是尽量将属性做成“私有的”—并通过共有的方法来向外提供对该属性的“可控性操作”
继承
多态:
多态:看起来用的是相同的方法但会得到不同的结果
通常指:一个对象可以使用相同的方法但得到不同的结果
Class A{
Function f1($x){}
Function f1($x, $y){……}
Function f1($x, $y, $z){……}
}
也指:不同的对象使用相同的方法但得到不同的结果