自定义的自动加载函数:
系统的自动加载函数仅有一个__autoload(), 有时候略显不方便, 咱们有时候还需要分别定义区别的函数, 去做为自动加载函数,
以应对区别的情形, 此时就能够运用自定义加载函数。 bool spl_autoload_register ([ callable $autoload_function [,bool $throw = true [, bool $prepend = false ]]] )
autoload_function 欲注册的自动装载函数。倘若无供给任何参数, 则自动注册 autoload 的默认实现函数spl_autoload()。
throw 此参数设置了 autoload_function 没法成功注册时, spl_autoload_register()是不是抛出反常。
prepend 倘若是 true, spl_autoload_register() 会添加函数到队列之首, 而不是队列尾部。 <?php
//1,先声明要做为自定义加载函数的函数名,能够多个:spl_autoload_register(auto1);
spl_autoload_register(auto2);
//2,分别定义这几个函数,其中写规律去加载需要的类文件。
function auto1($className){
echo "<h1>$className</h1>";
$file =./class/ . $className . .class.php;
if(file_exists($file)){ //file_exists()判断文件是不是存在
require_once $file;
}
}
function auto2($className){
echo "<h4>$className</h4>";
$file = ./library/ . $className . .class.php;
if(file_exists($file)){ //file_exists()判断文件是不是存在
require_once$file;
}
}//3,运用类,需要的时候就会自动依次调用这几个函数去完成加载工作。
$obj1 = new A();
$obj2 = new B();
var_dump($obj1,$obj2);
?>
PHP自动加载——PSR4规范
1.先来介绍一下PSR规范
PHP-FIG, 它的网站是:www.php-fig.org。便是这个联盟组织发明和创造了PSR规范, 其中自动加载触及其中两个规范, 一个是PSR0, 一个是PSR4, PSR0规范已然过时了,
官方有提示, 此刻重点是用PSR4规范定义自动加载标准。
PSR-4风格
类名:ZendAbc
命名空间前缀:Zend
文件基目录:/usr/includes/Zend/
文件路径: /usr/includes/Zend/Abc.php
类名:SymfonyCoreRequest
命名空间前缀:SymfonyCore
文件基目录:./vendor/Symfony/Core/
文件路径: ./vendor/Symfony/Core/Request.php
3. 自动加载办法 spl_autoload_register(function ($class) {
// 命名空间前缀
$prefix = Foo\\Bar\\;
// 命名空间前缀对应的基本目录
$base_dir = __DIR__ . /src/;
// 检测new的类是不是有命名空间前缀$len = strlen($prefix);if (strncmp($prefix, $class, $len) !== 0) {
return;
}
// 获取去掉命名空间前缀后的类名
$relative_class = substr($class, $len);
// 将命名空间的中的分隔符替换为目录分隔符,再加上基本目录和.php后缀,最后拼接成
// 文件路径
$file = $base_dir . str_replace(\\, /, $relative_class) . .php;
// 倘若文件存在则require
if (file_exists($file)) {
require$file;
}
});然则上面的办法只能适用固定的命名空间前缀, 不可通用。
4、再次优化通用自动加载办法 <?php
namespace Example;
/**
* 下面这个例子实现了一个命名空间前缀对应多个基本目录
*
* 此刻咱们的目录结构是下面这般:
*
* /demo/autoload/
* controller/
* DemoController.php # Foo\Bar\DemoController
* Admin/
* AdminController.php # Foo\Bar\Admin\AdminController
* model/
* DemoModel.php # Foo\Bar\DemoModel
* Admin/
* AdminModel.php # Foo\Bar\Admin\AdminModel
*
* Foo\Bar分别对应基本路径 /demo/autoload/controller 和 /demo/autoload/model
*/
class Psr4AutoloaderClass
{
/**
* 一个数组,key为命名空间前缀,值为基本路径
*
* @var array
*/
protected $prefixes = array();
/**
* 封装自动加载函数
*
* @return void
*/
public function register()
{
spl_autoload_register(array($this, loadClass));
}
/**
*
* 添加一个基本路径对应一个命名空间前缀
*
* @paramstring $prefix 命名空间前缀.
*@param string $base_dir 命名空间类文件的基本路径
* @param bool true为往数组头部添加元素,false为往数组尾部添加元素
* @return void
*/
public function addNamespace($prefix, $base_dir, $prepend = false)
{
// 去掉左边的\
$prefix = trim($prefix, \\) . \\;
// 规范基本路径$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) ./;
// 初始化数组
if (isset($this->prefixes[$prefix]) === false) {
$this->prefixes[$prefix] = array();
}
// 将命名空间前缀和基本路径存入数组
if($prepend) {
array_unshift($this->prefixes[$prefix], $base_dir);
} else {
array_push($this->prefixes[$prefix], $base_dir);
}
}
/**
* 真正包括文件办法,将给到类名文件包括进来
*
*@param string $class 全限定类名(包括命名空间).
* @return 成功将返回文件路径,失败则返回false
*/
public function loadClass($class)
{
$prefix = $class;
//查询$prefix最后一个\的位置,瞧瞧最后一个\之前的字符串是不是在$this->prefixes中
//倘若不存在则继续查找上一个\的位置,获取上一个\之前的字符串是不是在$this->prefixes中
//倘若循环结束还是无找到则返回false
while (false !== $pos = strrpos($prefix, \\)) {
$prefix = substr($class, 0, $pos + 1);
$relative_class = substr($class, $pos +1);
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
if ($mapped_file) {
return $mapped_file;
}
//去掉右边的\$prefix = rtrim($prefix,\\);
}
return false;
}
/**
* 倘若参数中的$prefix在$this->prefixes中存在,那样将循环$this->prefixes[$prefix]里的value(基本路径)
* 之后拼接文件路径,倘若文件存在将文件包括进来
*
*@param string $prefix 命名空间前缀.
* @paramstring $relative_class 真正的类名(不包括命名空间路径的类名).
*@return mixed 包括成功返回文件路径,否则返回false
*/
protected function loadMappedFile($prefix, $relative_class)
{
// 检测数组中是不是有$prefix这个key
if(isset($this->prefixes[$prefix]) === false) {
return false;
}
// 将数组中所有的基本路径中的文件包括进来
foreach ($this->prefixes[$prefix] as $base_dir) {
// 拼接文件绝对路径$file = $base_dir
. str_replace(\\, /, $relative_class)
. .php;
// 倘若文件存在则包括进来
if ($this->requireFile($file)) {
// 返回文件路径
return$file;
}
}// 无找到文件
return false;
}
/**
*倘若文件存在则包括进来.
*
* @param string $file 文件路径.
* @returnbool
*/
protected function requireFile($file)
{
if (file_exists($file)) {
require $file;
return true;
}
return false;
}
}
|