在封装类时,可以使用很多魔术方法。
PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),
前面课程中我们学习的构造方法__construct,析构方法 __destruct,就是其中的两个魔术方法。
以下是PHP所有的魔术方法,我们了解一下。
魔术方法包括:
- __construct(),类的构造函数
- __destruct(),类的析构函数
- __call(),在对象中调用一个不可访问方法时调用
- __callStatic(),用静态方式中调用一个不可访问方法时调用
- __get(),获得一个类的成员变量时调用
- __set(),设置一个类的成员变量时调用
- __isset(),当对不可访问属性调用isset()或empty()时调用
- __unset(),当对不可访问属性调用unset()时被调用。
- __sleep(),执行serialize()时,先会调用这个函数
- __wakeup(),执行unserialize()时,先会调用这个函数
- __toString(),类被当成字符串时的回应方法
- __invoke(),调用函数的方式调用一个对象时的回应方法
- __set_state(),调用var_export()导出类时,此静态方法会被调用。
- __clone(),当对象复制完成时调用
- __autoload(),尝试加载未定义的类
- __debugInfo(),打印所需调试信息
今天 我们要讲的是:__autoload(),为什么要学它呢?因为它与后面我们要学习的MVC有关,现在我们就简单学习一下。
__autoload(),这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数。看下面例子:
我们创建了一个test.php文件
<?php
//自动执行的函数,必须有一个参数
function __autoload($class){
echo $class;
}
//因为我们没有包含student类文件,当使用student类时,会自动执行__autoload函数
$stu = new Student();
$stu->say();
运行结果如下
其中的Student 是__autoload 函数输出的
下面的错误提示,是因为我们没有包含student类文件而造成的。
只要我们在__autoload函数,完成加载类文件,就能保证程序的正常执行。
接下来,我们创建一个student.php文件
<?php
class Student
{
public function say()
{
echo 'hello';
}
}
然后,我们改写test.php文件中的__autoload 函数
<?php
//自动执行的函数,必须有一个参数
function __autoload($class){
//$class 是传递过来的类名
//构建类文件的路径
$file = strtolower($class) . '.php';
//判断文件是否存在
if(is_file($file)){
//如果存在此文件,则包括该文件
require_once $file;
}else{
//如果没有此文件,则终止程序
die('类文件未找到');
}
}
//因为我们没有包含student类文件,当使用student类时,会自动执行__autoload函数
$stu = new Student();
$stu->say();
执行结果如下:
很明显示,程序能正常执行了。
autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。
如果,我们的student类有自己的命名空间,会发生什么情况呢?
student.php文件
<?php
namespace model;//此处添加了命名空间
class Student
{
public function say()
{
echo 'hello';
}
}
test.php文件
<?php
use model\Student;
//自动执行的函数,必须有一个参数
function __autoload($class){
//$class 是传递过来的类名
//构建类文件的路径
$file = strtolower($class) . '.php';
//判断文件是否存在
if(is_file($file)){
//如果存在此文件,则包括该文件
require_once $file;
}else{
//如果没有此文件,则终止程序
die('类文件未找到');
}
}
//因为我们没有包含student类文件,当使用student类时,会自动执行__autoload函数
$stu = new Student();
$stu->say();
运行结果如下
给类添加了命名空间后,为什么找不到类文件呢?
因为此时的_autoload函数接收到的参数值是:model\Student
此时构建的文件路径是:model\Student.php
所以当test.php和student.php在同一个目录时,当然找不到类文件了。
我们需要把student.php放到下一级目录model中
test.php和student.php之间的目录关系如下:
同时,我们改写__autoload中的部分代码
<?php
use model\Student;
//自动执行的函数,必须有一个参数
function __autoload($class){
//$class 是传递过来的类名
//构建类文件的路径
//注意__DIR__ 和转义字符 \ 的使用
$file =__DIR__ ."\\". strtolower($class) . '.php';
//判断文件是否存在
if(is_file($file)){
//如果存在此文件,则包括该文件
require_once $file;
}else{
//如果没有此文件,则终止程序
die('类文件未找到');
}
}
//因为我们没有包含student类文件,当使用student类时,会自动执行__autoload函数
$stu = new Student();
$stu->say();
按照以上步骤改造完成后,程序又能正常执行了。
总结:
__autoload函数 :主要的功能就是构造需要加载的类文件的路径,然后包括包含类文件。这一切都是当程序找不到类文件时自动执行的。