php自动加载 依赖,php自动加载

php的自动加载

自动加载原理

我们使用另一个文件定义的一个class的时候,传统的情况下需要require XXX.php

//Good.php

class Good{

//......

}

//use.php

require 'Good.php'; //包含进来文件

$good = new Good(); //现在可以使用Good类

但是写require真的很烦!!现在可以使用一个自动加载函数,发现类没有被定义的时候自动根据我们定义的规则帮我们去require需要的文件。

//Good.php

class Good{

//......

}

//use.php

function __autoload($className){

require $className . '.php'; //定义包含的规则

}

$good = new Good(); //可以使用Good类,发现没有定义,会自动调用__autoload函数,现在'Good'作为参数传入了__autoload函数,去包含需要的文件

spl_autoload_register

__autoload函数不能解决所有的问题,现在的项目已经非常复杂,光一个autoload函数已经不能满足需要了,因为可能不同的模块使用了不同的自动加载规则。

spl_autoload_register将函数注册到SPL autoload函数队列中,它实际上创建了 __autoload 函数的队列,按定义时的顺序逐个执行。相比之下,__ 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() 会添加函数到队列之首,而不是队列尾部。

函数使用

sql_autoload_resister('load_function'); //函数名

sql_autoload_resister(array('load_object', 'load_function')); //类和静态方法

sql_autoload_resister('load_object::load_function'); //类和方法的静态调用

//php 5.3之后,也可以像这样支持匿名函数了。

spl_autoload_register(function($className){

if (is_file('./lib/' . $className . '.php')) {

require './lib/' . $className . '.php';

}

});

note:使用了spl_autoload_register之后原来的__autoload函数就失效了,如果需要继续使用,需要显示的注册它

if (function_exists('__autoload')) {

spl_autoload_register('__autoload');

}

//。。。。。。

spl_autoload_register('your_autoload_function'); //现在注册另一个

是否继续在自动加载函数队列中查找不取决于加载函数的返回值和是否require了文件,只有真正require需要的文件才会停止

//Good.php位于app文件夹下

class Good{

//......

}

//Another.php,位于use同级文件夹下

class Another{

}

//use.php

function load1($className)

{

echo "load1n";

if (file_exists($className.'.php')) {

echo 'found: '.$className.PHP_EOL;

require $className;

} else {

echo 'not found: '.$className.PHP_EOL;

}

}

function load2($className)

{

echo "load2n";

require 'Another.php';

echo 'require another class'.PHP_EOL;

return true;

}

function load3($className)

{

echo "load3n";

if (file_exists('app/'.$className.'.php')) {

echo 'found '.$className.PHP_EOL;

require 'app/'.$className.'.php';

} else {

echo 'not found: '.$className.PHP_EOL;

}

}

spl_autoload_register('load1');

spl_autoload_register('load2');

spl_autoload_register('load3');

$a = new Good();

输出如下

load1

not found: Good

load2

require another class

load3

found Good

可以使用spl_autoload_functions()获得注册的所有函数

Array

(

[0] => load1

[1] => load2

[2] => load3

)

取消注册的自动加载函数spl_autoload_unregister

spl_autoload_unregister('load1');

spl_autoload()是__autoload()函数的默认实现

提供了autoload()的一个默认实现。如果不使用任何参数调用 spl_autoload_register() 函数,则以后在进行 autoload() 调用时会自动使用此函数。

自动加载和命名空间

PSR-4自动加载规范

标准的类名应该具有下列形式

()*

需要强调的:

完整的类名中任意一部分中的下滑线都是没有特殊含义的

所有类名都必须是大小写敏感的

所有类名都必须是大小写敏感的

当根据命名空间载入文件时候:

完整的类名中,去掉最前面的命名空间分隔符,前面连续的一个或多个命名空间和子命名空间,作为“命名空间前缀”,其必须与至少一个“文件基目录”相对应。

紧接命名空间前缀后的子命名空间必须与相应的”文件基目录“相匹配,其中的命名空间分隔符将作为目录分隔符。

末尾的类名必须与对应的以 .php 为后缀的文件同名。

自动加载器(autoloader)的实现一定不能抛出异常、一定不能触发任一级别的错误信息以及不应该有返回值。

例子

完整类名

命名空间前缀

文件基目录

文件路径AcmeLogWriterFile_Writer

AcmeLogWriter

./acme-log-writer/lib/

./acme-log-writer/lib/File_Writer.php

AuraWebResponseStatus

AuraWeb

/path/to/aura-web/src/

/path/to/aura-web/src/Response/Status.php

SymfonyCoreRequest

SymfonyCore

./vendor/Symfony/Core/

./vendor/Symfony/Core/Request.php

ZendAcl

Zend

/usr/includes/Zend/

/usr/includes/Zend/Acl.php

实现示例

采用了匿名函数的方式

/**

* An example of a project-specific implementation.

*

* After registering this autoload function with SPL, the following line

* would cause the function to attempt to load the FooBarBazQux class

* from /path/to/project/src/Baz/Qux.php:

*

* new FooBarBazQux;

*

* @param string $class The fully-qualified class name.

* @return void

*/

spl_autoload_register(function ($class) {

// project-specific namespace prefix

$prefix = 'Foo\Bar\';

// base directory for the namespace prefix

$base_dir = __DIR__ . '/src/';

// does the class use the namespace prefix?

$len = strlen($prefix);

if (strncmp($prefix, $class, $len) !== 0) {

// no, move to the next registered autoloader

return;

}

// get the relative class name

$relative_class = substr($class, $len);

// replace the namespace prefix with the base directory, replace namespace

// separators with directory separators in the relative class name, append

// with .php

//下边这一行很关键

$file = $base_dir . str_replace('\', '/', $relative_class) . '.php';

// if the file exists, require it

if (file_exists($file)) {

require $file;

}

});

参考资料:

内容来源于网络如有侵权请私信删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值