您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
Ready 发布于2013年09月07日 06:46 最近更新于 2019年06月01日 11:41

原创 PHP使用__autoload()自动加载未定义的类

2406 次浏览 读完需要≈ 9 分钟 PHP

内容目录

稍微了解PHP发展历史的人都知道,PHP最初诞生的时候只支持面向过程化的编码方式,不过随着PHP在web开发领域越来越流行以及大型web站点建设的需要,从PHP 4开始,PHP也开始支持面向对象编程了。此外,随着PHP 5的发布,尤其是PHP针对面向对象特性的不断完善,在目前的PHP程序开发中,面向对象编程以及基于面向对象的PHP MVC框架的程序开发已经成了主流的选择。

下面,我们先来看一个简单的PHP Class(类)的代码示例:

<?php
/**
 * 用于表示网站站点的PHP类
 */
class Site{
	public $name;	//站点名称
	public $email;	//站点邮箱
	public $url;	//站点网址
	
	//显示欢迎信息的函数
	public function sayHi(){
		echo "欢迎来到{$this->name}({$this->url}),你可以发送邮件到{$this->email}来联系我!";
	}
}

$site = new Site();	//实例化一个Site(站点)对象
$site->name = 'CodePlayer';
$site->email = 'admin@365mini.com';
$site->url = 'https://codeplayer.vip';

$site->sayHi();
//输出:欢迎来到CodePlayer(https://codeplayer.vip),你可以发送邮件到admin@365mini.com来联系我!
?>

在上面的例子中,为了便于理解,我们将类的定义和相关调用放在了同一个文件中。不过,在正式的程序开发中,我们一般会将单个类的定义放在一个PHP文件中,并且PHP文件的名称一般命名为类名.class.php。这样,在需要使用该类的时候,我们只需要调用require_oncerequireinclude等指令来包含该类文件即可。譬如,上面的例子,我们将其拆分为两个文件,两个文件(Site.class.phpsample.php)的代码分别如下:

<?php
/**
 * 用于表示网站站点的PHP类
 */
class Site{
	public $name;	//站点名称
	public $email;	//站点邮箱
	public $url;	//站点网址
	
	//显示欢迎信息的函数
	public function sayHi(){
		echo "欢迎来到{$this->name}({$this->url}),你可以发送邮件到{$this->email}来联系我!";
	}
}
?>
<?php
require_once 'Site.class.php';	//包含Site.class.php文件
$site = new Site();	//实例化一个Site(站点)对象
$site->name = 'CodePlayer';
$site->email = 'admin@365mini.com';
$site->url = 'https://codeplayer.vip';

$site->sayHi();
//输出:欢迎来到CodePlayer(https://codeplayer.vip),你可以发送邮件到admin@365mini.com来联系我!
?>

不过,这样仍然感觉有些麻烦,尤其是在大型站点的程序开发中,涉及到的类可能非常多,需要使用这些类的PHP文件当然就更多了,如果每个需要使用的地方都来上几句require_once(或其他包含指令),那是不是就感觉有些繁琐了呢,而且这样也不利于后期的程序维护。于是我们思考,有没有这样一种方式:只要我们创建(new)一个类的对象,并且之前的代码也没有包含对应类的定义文件,PHP就能帮我们自动将对应的类文件包含进来呢?

答案当然是肯定的,从PHP 5开始,PHP为我们提供了一个神奇的函数——__autoload(),它就可以帮我们实现这样的功能。只要我们在使用类之前定义一个名为__autoload()的函数,当我们在PHP中new一个类的实例时,如果PHP在之前的运行代码中找不到该类的定义,那么它就会自动调用__autoload()函数,并且将对应的类名作为参数传递进去。

这里,我们来看一个具体的例子,假设我们将所有的类定义文件都放在PHP站点根目录的class文件夹下,并且类定义文件的命名方式统一为类名.class.php。那么,我们就可以如下编写__autoload()函数。

<?php
define('ABSPATH', dirname(__FILE__)); //定义ABSPATH常量,用于表示站点根目录的绝对路径
/**
 * 自动加载未定义的类文件
 * @param string $classname
 */
function __autoload($classname){
	require_once ABSPATH.'/class/'.$classname.'.class.php';			
}
?>
<?php
require_once 'functions.php';	//包含进定义__autoload()函数的文件
$site = new Site();	//实例化一个Site(站点)对象,此时自动调用__autoload()函数
$site->name = 'CodePlayer';
$site->email = 'admin@365mini.com';
$site->url = 'https://codeplayer.vip';

$site->sayHi();
//输出:欢迎来到CodePlayer(https://codeplayer.vip),你可以发送邮件到admin@365mini.com来联系我!

//$p = new Person(); 如果还要使用其他类对象,直接创建即可
//$emp = new Employee();
?>

注意:在Windows操作系统中,由于其文件系统不区分大小写,因此类的名称与类定义文件的名称的大小写可以不一致。例如,PHP类名为Person,定义该类的PHP文件名称为person.class.phpPerson.class.php均不会出错。不过在Linux操作系统中,由于其文件系统默认区分大小写,因此类的名称与类定义文件的名称的大小写需保持一致,否则将会报错。 为了兼容考虑,建议类名与类定义文件的名称最好保持大小写一致。

  • CodePlayer技术交流群1
  • CodePlayer技术交流群2

0 条评论

撰写评论