1 变量作用域
- PHP中分为3种类型的变量:全局变量(函数外)、局部变量(函数内)、超全局变量
- 局部变量在函数运行结束后删除,全局变量在页面关闭后删除
- 全局变量不能在函数内使用,局部变量不能在函数外使用
2 global
- 允许函数外的变量在函数内使用,或函数内的变量在函数外使用
- 原理是将全局变量的地址,引入到函数中,即引用传地址
- global只能在函数内使用才有效
- 删除函数内部的全局变量,即为断开到函数外的连接,而非真正删除
$name="kakura";
function test(){
//将全局变量的地址,引入到函数
global $name;
$name="神乐";
echo "函数内:{$name}";//输出神乐
//断开函数内部的全局变量,断开到函数外的连接
unset($name);
}
test();
echo "函数外:{$name}";//输出kakura
3 $GLOBALS超全局数组变量
- 出现过的全局变量,就可以通过$GLOBALS这个数组获得
- $GLOBALS数组中包括:全局变量、$_GET、$_POST、$_FILRS、$_COOKIE
- 在函数内删除超全局变量,函数外也不存在了
$name="kakura";
function test(){
$GLOBALS['name']="神乐";
$GLOBALS['age']=70;
echo "函数内:".$GLOBALS['name'];//输出神乐
echo "函数内:".$GLOBALS['age'];//输出70
}
test();
echo "函数外:{$name}";//输出神乐
echo "函数外:{$age}";//输出70
4 变量引用传递“&”
- 在PHP中,对象和资源默认使用引用传值
$var1=1;
$var2=8;
function test(){
global $var1,$var2;//同名引用传地址
$var1=&$var2;//&引用传地址,$var1的地址指向了$var2
//因此,在函数内没有$var1,2个都是$var2
$var1=80;
echo "$var1,$var2<br>"; //var1=80 var2=80
}
test();
echo "$var1,$var2<br>"; //var1=1 var2=80
5 接口技术
- PHP只支持单继承,只能从一个父类来继承功能;如果PHP想从多个父类同时继承,可以使用接口实现;接口也是子类中方法的命名规范
- 接口就是特殊的抽象类
5.1接口定义的实习要点
- interface关键字,原理声明一个接口。接口是一种特殊类
- implements关键字,创建一个子类,来实现接口。
- 同类的东西,使用extends关键字;不同类的东西,使用implements关键字
- 子类继承父类,接口继承接口,类实现接口
- 接口中只能存在2样东西:类常量、抽象方法
- 接口中的方法,默认都是抽象方法,所以不需要加abstract关键字
- 接口中的方法,可以是成员方法,或静态方法
- 接口中的抽象方法,子类必须重写
- 接口中的常量不能重写,只能继承
- PHP中的重写不一定是方法重写,还可以是常量重写、静态属性重写、静态方法重写
//定义手机接口
interface Phone{
//打电话
public function tel();
}
//定义MP3接口
interface MP3{
//听音乐
public function music();
}
//定义MP4接口,并继承MP3接口
interface MP4 extends MP3{
//看电影
public function video();
}
//定义智能手机的类,实现以上多个接口
class Mobie implements Phone,MP3,MP4{
//重写tel抽象方法
public function tel(){
echo"<br>打电话!";
}
//重写music抽象方法
public function music(){
echo"<br>听音乐!";
}
//重写video抽象方法
public function video(){
echo"<br>看电影!";
}
//定义玩游戏的方法
public function game(){
echo"<br>玩游戏!";
}
}
//对象实例化
$obj=new Mobie();
$obj->tel();
$obj->music();
$obj->video();
$obj->game();
6 类的自动加载
6.1 为什么需要类的自动加载
- 程序员做开发时,会把每一个功能,都定义成一个独立的类文件,类文件以“.class.php”结尾。若一个大项目有50个功能,就有50个类文件,在应用页面,就需要把相关类文件用require()、require_once()包含进页面。那么在页面开头会有50个require_once(),极大浪费内存空间,把不需要的类也包含进来
- 如何解决文件加载问题?按需加载
6.2 常规的自动加载类函数 __autload()(已经废弃不用)
6.2.1 类文件命名规范
- 将每一个功能,单独定义成一个类文件
- 每一个类文件,尽量以“.class.php”结尾
- 类文件主名,要与类名一致
- 类名命名方式,尽量使用驼峰式命名,每个单词首字母大写
- 方法命名方式,尽量使用驼峰式命名,第一个单词小写,之后每个单词首字母大写
- 属性命名方式,尽量使用驼峰式命名,第一个单词小写,之后每个单词首字母大写
6.2.2 __autoload()函数语法
- __autoload()是系统函数,不是方法
- 我们需要定义该函数内容
- 该函数有一个唯一参数,就是类名函数
- 当使用一个不存在的类时,__autoload($className)会自动调用
- 当使用new关键字,创建一个不存在的类对象时,__autoload()自动调用。如:$obj=new Student()
- 当使用静态化方法调用不存在类的属性或方法时,__autoload()自动调用。如:Student::getCode()
- 当继承一个不存在的父类时,__autoload()自动调用。如:calss Student extends Teacher{}
- 当实现一个不存在的接口类时,__autoload()自动调用。如:calss Student implements Inter{}
- 函数的内容包含2方面
- 构建类文件的真是路径
- 判断并包含文件代码
//类的自动加载
function __autoload($calssNmae){ //由于已经废弃,会报错
//构建类文件的真实路径
$fileNmae="./$calssNmae.class.php";
//如果类文件存在,则包含
if (file_exists($fileNmae))
require_once ($fileNmae);
}
6.3 自定义类文件加载函数(spl_autoload_register)
- 一个项目中只能定义一个__autoload,假如说当项目中引用了第三方文件时,刚好第三方文件中也使用__autoload;或者项目成员多的时候,定义了不同的 __autoload; 此时就会出错,因为__autoload函数拥有全局域,php也支不支持函数重载,只能将几个__autoload合并成一个。
- 于是就有了更加灵活的spl_autoload_register()的自动加载机制,php官方也建议不要使用__autoload而使用spl_autoload_register()。
- spl_autoload_register可以注册多个类加载函数,形成了一个类文件的队列
- 每个函数就是第一种类文件的加载规则
//类的自动加载
spl_autoload_register('autoload1');
spl_autoload_register('autoload2');
function autoload1($calssNmae){
//构建类文件的真实路径
$fileNmae="./$calssNmae.class.php";
//如果类文件存在,则包含
if (file_exists($fileNmae))
require_once ($fileNmae);
}
function autoload2($calssNmae){
//构建类文件的真实路径
$fileNmae="../file/$calssNmae.class.php";
//如果类文件存在,则包含
if (file_exists($fileNmae))
require_once ($fileNmae);
}
//创建学生类对象
$stuObj=new Student();
//创建老师类对象
$teaObj=new Teacher();
6.4使用匿名函数参数
//类的自动加载
spl_autoload_register(function($className){
//类文件路径的数组
$arr=array(
"./$className.class.php",
"../file/$className.class.php"
);
//循环数组
foreach ($arr as $fileName){
//如果类文件存在,则包含
if (file_exists($fileName))
require_once ($fileName);
}
});
7 对象克隆
7.1 什么是克隆对象
- 创建新对象有2种方式:(1)使用new关键字(2)使用clone关键字
class Student{
private $name="kakura";
private $age=70;
//当对象克隆完成时,魔术方法__clone()会自动调用
public function __clone(){
$this->name="神乐";
$this->age=24;
}
}
//创建学生类对象
$obj1=new Student();
//克隆新对象
$obj2=clone $obj1;
var_dump($obj1,$obj2);
8 对象遍历
- 在类内遍历所有对象属性
- 在类外只能遍历公共对象属性
//定义学生类
class Student{
private $name="kakura";
protected $age=70;
public $city="珠海";
//在类中遍历对象所有属性
public function showAllAttrs(){
foreach ($this as $k=>$v) {
echo "\$obj->$k=$v<br>";
}
}
}
//创建学生类对象
$obj1=new Student();
//在类外遍历公共的对象属性
foreach ($obj1 as $k=>$v) {
echo "\$obj->$k=$v<br>";
}
echo "<hr>";
$obj1->showAllAttrs();
输出:
9 魔术方法
9.1 __toString()
- 将对象转成字符时,魔术方法__toString()自动调用
class Student{
//当将对象转换成字符串时,__toString()会自动调用
public function __toString(){
return "对象不能转字符串";
}
}
//创建学生类对象
$obj1=new Student();
//将对象转成字符串,然后输出
echo $obj1;
输出:
9.2 __invlke()
- 当把对象当成函数调用,魔术方法__invlke()自动调用
class Student{
//当将对象当成函数时,__invoke()会自动调用
public function __invoke(){
echo "对象不能当成函数调用";
}
}
//创建学生类对象
$obj1=new Student();
//将对象当成函数调用
$obj1();