spl_autoload_register

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

spl_autoload_register将给定函数注册为 __autoload() 实现

描述

spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool

将函数注册到 spl 提供的 __autoload 队列中。如果队列尚未激活,它将被激活。

如果您的代码具有现有的 __autoload() 函数,那么该函数必须在 __autoload 队列上显式注册。这是因为 spl_autoload_register() 将有效地用 spl_autoload()spl_autoload_call() 替换 __autoload() 函数的引擎缓存。

如果必须有多个自动加载函数,spl_autoload_register() 允许这样做。它有效地创建一个自动加载函数队列,并按定义顺序运行每个函数。相比之下,__autoload() 只能定义一次。

参数

callback

要注册的自动加载函数。如果为 null,则将注册 spl_autoload() 的默认实现。

callback(string $class): void

class 不会包含完全限定标识符的开头反斜杠。

throw

此参数指定 spl_autoload_register()callback 无法注册时是否抛出异常。

警告

从 PHP 8.0.0 开始,此参数被忽略,如果设置为 false,将发出通知。 spl_autoload_register() 现在将始终对无效参数抛出 TypeError

prepend

如果为 truespl_autoload_register() 将在自动加载队列上预先添加自动加载器,而不是追加它。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 描述
8.0.0 callback 现在可以为空。

示例

示例 #1 spl_autoload_register() 作为 __autoload() 函数的替代品

<?php

// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
include
'classes/' . $class . '.class.php';
}

spl_autoload_register('my_autoloader');

// 或者,使用匿名函数
spl_autoload_register(function ($class) {
include
'classes/' . $class . '.class.php';
});

?>

示例 #2 spl_autoload_register() 示例,其中未加载类

<?php

namespace Foobar;

class
Foo {
static public function
test($class) {
print
'[['. $class .']]';
}
}

spl_autoload_register(__NAMESPACE__ .'\Foo::test');

new
InexistentClass;

?>

上面的示例将输出类似以下内容

[[Foobar\InexistentClass]]
Fatal error: Class 'Foobar\InexistentClass' not found in ...

示例 #3 标识符将不带开头反斜杠提供

<?php

spl_autoload_register
(static function ($class) {
var_dump($class);
});

class_exists('RelativeName');
class_exists('RelativeName\\WithNamespace');
class_exists('\\AbsoluteName');
class_exists('\\AbsoluteName\\WithNamespace');

?>

上面的示例将输出

string(12) "RelativeName"
string(26) "RelativeName\WithNamespace"
string(12) "AbsoluteName"
string(26) "AbsoluteName\WithNamespace"

参见

添加注释

用户贡献注释 30 条注释

204
a dot schaffhirt at sedna-soft dot de
15 年前
使用命名空间类的 PHP 5.3 用户的好消息

当您创建与包含类的命名空间相匹配的子文件夹结构时,您甚至不必定义自动加载器。

<?php
spl_autoload_extensions
(".php"); // 逗号分隔列表
spl_autoload_register();
?>

建议为所有类使用一个扩展名。PHP(更准确地说是 spl_autoload)会为您完成剩下的工作,并且比像这样的语义上等效的自定义自动加载函数更快

<?php
function my_autoload ($pClassName) {
include(
__DIR__ . "/" . $pClassName . ".php");
}
spl_autoload_register("my_autoload");
?>

我将它们与以下设置进行了比较:有 10 个文件夹,每个文件夹有 10 个子文件夹,每个子文件夹有 10 个子文件夹,每个子文件夹包含 10 个类。

为了加载和实例化这 1000 个类(无参数无操作构造函数),用户定义的自动加载函数方法在平均情况下比 spl_autoload 函数慢 50 毫秒,在一系列 10 次命令行调用中,每次调用使用一种方法。

我进行这个基准测试是为了确保我不会推荐以后会被称为“不错,但速度慢”的东西。

此致,
23
nemanja
7 年前
即使使用自动加载(SPL),类继承似乎也不起作用。PHP 引擎只是无法找到父类(继承)类。PHP 5.6 和 7.0 在这方面表现完全相同,这违背了自动加载的目的。

我认为这很容易解决,因为自动加载器可以毫无问题地找到所有第一级类,它只需要在父级上递归地遵循相同的路径即可。

<?php
// 使用默认 SPL 自动加载器,将命名空间 1:1 映射到目录结构,文件名全部小写。
// 此方法仅适用于第一级类,对于继承不适用,无法找到父类。
spl_autoload_register();

// 以下代码虽然丑陋,但如果需要自动加载父类,则可以使用。
spl_autoload_register(function ($class){
require_once
__DIR__ . '/' . strtolower(str_replace('\\', '/', $class) . '.php');
});
4
abhijeet dot sweden at gmail dot com
2 年前
类型#1

<?php

require_once('Second.php');
require_once(
'First.php');

$Second = new Second;
$Second->run_second();

$First = new First;
$First->run_first();

?>

---------------------------------------------------------
类型#2

<?php

spl_autoload_register
(function($class){
//
require_once($class.'.php');
});

$Second = new Second;
$Second->run_second();

$First = new First;
$First->run_first();

?>
12
kuzawinski dot marcin at nospam dot gmail dot com
3 年前
从 PHP 8.0 开始,spl_autoload_register() 在遇到无效参数时将始终抛出 TypeError,因此第二个参数 `throw` 被忽略,如果设置为 False,则会发出通知。
30
eyeofmidas at gmail dot com
9 年前
从使用 __autoload() 切换到使用 spl_autoload_register 时,请记住,会话的序列化可能会触发类查找。

此代码按预期工作
<?php
session_start
();
function
__autoload($class) {
...
}
?>

此代码在使用从会话中反序列化的类时会导致 "__PHP_Incomplete_Class_Name" 错误。
<?php
session_start
();
function
customAutoloader($class) {
...
}
spl_autoload_register("customAutoloader");
?>

因此,您需要确保在调用 session_start() 之前完成 spl_autoload_register。

正确
<?php
function customAutoloader($class) {
...
}
spl_autoload_register("customAutoloader");
session_start();
?>
44
(delphists) at (apollo) dot (lv)
13 年前
在使用 spl_autoload_register() 和类方法时,可能看起来只能使用公共方法,但如果从类内部注册,也可以使用私有/保护方法。
<?php

class ClassAutoloader {
public function
__construct() {
spl_autoload_register(array($this, 'loader'));
}
private function
loader($className) {
echo
'Trying to load ', $className, ' via ', __METHOD__, "()\n";
include
$className . '.php';
}
}

$autoloader = new ClassAutoloader();

$obj = new Class1();
$obj = new Class2();

?>

输出
--------
Trying to load Class1 via ClassAutoloader::loader()
Class1::__construct()
Trying to load Class2 via ClassAutoloader::loader()
Class2::__construct()
15
iam at thatguy dot co dot za
9 年前
<?php

// 使用 SPL_AUTOLOAD_REGISTER 方法,从多个目录自动加载类文件。
// 它自动加载所有以 class.<classname>.php 开头的文件(小写),例如:class.from.php,class.db.php
spl_autoload_register(function($class_name) {

// 定义一个目录数组,按优先级顺序进行迭代。
$dirs = array(
'project/', // 项目特定的类(+核心覆盖)
'classes/', // 核心类示例
'tests/', // 单元测试类,如果使用 PHP-Unit
);

// 循环遍历每个目录以加载所有类文件。它只会加载一次文件。
// 如果它在后面的目录中找到相同的类,它将忽略它!因为使用了 require_once!
foreach( $dirs as $dir ) {
if (
file_exists($dir.'class.'.strtolower($class_name).'.php')) {
require_once(
$dir.'class.'.strtolower($class_name).'.php');
return;
}
}
});
20
florent at mediagonale dot com
17 年前
如果您的自动加载函数是一个类方法,您可以使用一个数组指定要运行的类和方法,来调用 spl_autoload_register。

* 您可以使用静态方法
<?php

class MyClass {
public static function
autoload($className) {
// ...
}
}

spl_autoload_register(array('MyClass', 'autoload'));
?>

* 或者您可以使用实例
<?php
class MyClass {
public function
autoload($className) {
// ...
}
}

$instance = new MyClass();
spl_autoload_register(array($instance, 'autoload'));
?>
20
anthon at piwik dot org
14 年前
谨慎考虑从注册的自动加载器中抛出异常。

如果您注册了多个自动加载器,并且一个(或多个)在后面的自动加载器加载类之前抛出异常,即使类已成功加载,也会抛出堆叠异常(并且必须捕获)。
16
a dot schaffhirt at sedna-soft dot de
11 年前
我之前在这里所说的话只适用于 Windows。当您不带任何参数调用 spl_autoload_register() 时注册的内置默认自动加载器只是将限定的类名加上注册的文件扩展名(.php)添加到每个包含路径,并尝试包含该文件。

示例(在 Windows 上)

包含路径
- "."
- "d:/projects/phplib"

要加载的限定类名
network\http\rest\Resource

以下是发生的情况

PHP 尝试加载
'.\\network\\http\\rest\\Resource.php'
-> 文件未找到

PHP 尝试加载
'd:/projects/phplib\\network\\http\\rest\\Resource.php'
-> 文件已找到并包含

请注意文件路径中的斜杠和反斜杠。在 Windows 上,此方法完美运行,但在 Linux 计算机上,反斜杠将无法正常工作,此外文件名区分大小写。

因此,在 Linux 上,简单快捷的方法是将这些限定的类名转换为斜杠和小写,并将它们传递给内置自动加载器,如下所示

<?php
spl_autoload_register
(
function (
$pClassName) {
spl_autoload(strtolower(str_replace("\\", "/", $pClassName)));
}
);
?>

但这意味着您必须将所有类以小写文件名保存。否则,如果您省略 strtolower 调用,则必须使用与文件名完全一致的类名,这对于以非直观大小写定义的类名(例如 XMLHttpRequest)可能会很麻烦。

我更喜欢小写方法,因为它更容易使用,并且可以在部署时自动进行文件名转换。
22
Anonymous
14 年前
在区分大小写的文件系统上使用此函数时要小心。

<?php
spl_autoload_extensions
('.php');
spl_autoload_register();
?>

我在 OS X 上开发,一切正常。但是,当我发布到我的 Linux 服务器时,没有一个类文件加载。我必须将所有文件名改为小写,因为调用一个名为 "DatabaseObject" 的类会尝试包含 "databaseobject.php",而不是 "DatabaseObject.php"

我想我会回到使用速度较慢的 __autoload() 函数,这样我就可以保持类文件可读。
6
phil at propcom dot co dot uk
10 年前
需要注意的是,如果 E_STRICT 错误触发了错误处理程序,而错误处理程序又尝试使用尚未加载的类,则不会调用自动加载程序。

在这种情况下,您应该手动加载错误处理程序所需的类。
7
rayro at gmx dot de
14 年前
在自动加载函数中使用 eval 创建类从来都不是一个好主意,而且是一个不可取的概念。
这对于异常来说应该是一个不错的功能,但我认为任何人都可以在没有这种方法的情况下处理它。目前我还没有意识到这有什么用处...

正如我可能注意到的,class_exists() 将始终定义你只想检查是否存在,因此将始终返回 true 的类。
<?php
function EvalIsEvil($class) {
eval(
'class '.$className.'{}');
}
spl_autoload_register('EvalIsEvil');
if (
class_exists($s="IsMyModuleHere")) {
// 这不是一个模块,而是通过 eval() 获取的...
return new $s();
}
?>
3
rnealxp at yahoo dot com
7 年前
我现在使用 spl_autoload_register,而且再也不会回头了。所以让我在这里为你总结一下我学到的东西...
1.) 这些文档中提到的关于文件名大小写敏感(Windows 与 Linux/Mac)的问题:只有在你调用 spl_autoload_register 时没有提供自定义函数作为参数时才会出现。你的函数应该接受一个参数,该参数将是你的代码当前试图访问的类名。我观察到类名以你实际在代码库中使用的字母大小写(混合大小写或不)出现。我没有使用/使用命名空间,但作为最佳实践,为了使你的实现直观和可预测,请使用 fileName===className (1:1)。
2.) 我经常在我的代码库的目录结构发生变化时重构它。我没有使用命名空间,但即使我使用命名空间,我也希望我的命名空间层次结构和我的目录结构层次结构之间解耦。我喜欢我的目录层次结构直观,以便获取我要使用的代码。为了避免手动告诉我的自动加载程序每个文件/类的路径,我在静态变量中缓存了几个数组,这些数组在一个数组中存储了文件/类名,在另一个数组中存储了文件的文件夹路径。在第一次调用我的函数后,缓存(静态变量)被设置,只需在文件名数组中查找即可。为了安全起见,为了避免出现问题,所有 php 文件名在你的整个目录层次结构中不应相同(你的命名空间) - 我无论如何都喜欢这种做法,因此,我倾向于在单个命名空间中使用唯一的类名(尽管它还没有明确定义)。我在我的函数中内置了一个检查,以确保所有 php 文件名/类都是唯一的。
3.) 我将许多曾经在全局空间中有一组函数的文件转换为 *抽象类*,这些类具有私有静态变量和方法,当然还有公共静态方法。因此,这些函数集现在封装在对象中,这些对象现在是自动加载的。仅仅为了这个好处,我将不再在全局空间中使用函数,除了我的自动加载函数和其他例外情况,例如。
4.) 我的自动加载函数仅使用内置的 php 语言结构和操作,没有外部依赖项。
5.) 如果你在你的代码库中的某个地方使用了函数 class_exists(),请意识到,除非你将第二个参数设置为 false,否则你将触发自动加载程序加载该类。我当然也遇到了这个问题。我的用例是我不希望加载该类:我只想在使用该类时(在错误处理程序方法中)采取一些措施。
6.) 如果你使用函数 method_exists(),你将一定会触发加载该类(这是有道理的,因为你已经决定深入查找特定方法)。
7.) 我在这里感谢其他人的想法:我也选择为被加载的类调用一个 init() 方法,如果它存在。这避免了我必须从外部手动调用,更不用说管理调用应该如何以及从哪里进行。以这种自动化方式为你的对象进行设置并准备工作是如此有用。
8.) 正如其他人所说,我也使用 require() 而不是 require_once(),因为前者足以生成错误,如果已经加载,则该函数不会被调用。
9.) 如果由于某种原因,我在我的缓存数组中找不到类名,我仍然会有意调用 require(),传递我没有考虑到的类名,以生成和揭示问题(当然,这是没有预料到的!)。
10.) 我再次确保所有类名都是唯一的。如果我观察到不唯一,我再次对 require() 进行错误调用,如下所示:require('FoundMultiplesOfClassFile.php');以揭示问题。(我还没有,你也不应该,有任何复杂的错误处理程序注册,所以对我来说,这和任何其他方法一样好)。
2
daniel at amnistechnology dot com
11 年前
我注意到(至少在 PHP 5.3 中),这些自动加载程序即使在调用尚未加载的全部静态类的公共静态方法时也会“启动”,这非常巧妙和有用。
4
sebastian dot krebs at kingcrunch dot de
14 年前
似乎,spl_autoload 在调用每个注册的加载程序后会测试类是否存在。因此,如果类存在,它会中断链,并且不会调用其他加载程序。

<?php
function a ($c) {
echo
"a\n";
class
Bla {} // 通常是 "include 'path/to/file.php';"
}
function
b ($c) {
echo
"b\n";
}
spl_autoload_register('a');
spl_autoload_register('b');

$c = new Bla();
?>
1
kakkau at grr dot la
8 年前
关于使用附加参数注册自动加载函数的说明。

./alf.home.php
<?php
/*
* 包含自动加载函数别名 ALF 的类 :)
*/
class ALF {
public function
haaahaaahaaa($class = "ALF", $param = "Melmac") {
echo
"I am ".$class." from ".$param.".\n";
}
}
?>

./kate.melmac.php
<?php
require_once("alf.home.php");
/*
* 正常的方法是获取 ALF
* 并注册一个自动加载函数
*/
$alf = new ALF();
spl_autoload_register(array($alf,'haaahaaahaaa'));
$alf->haaahaaahaaa(); // ALF 来自 Melmac :)
/*
* 现在尝试自动加载一个类
*/
@$kate = new Kate(); // 这会抛出一个致命错误,因为
// Kate 不来自 Melmac :)
?>
I am ALF from Melmac.
I am Kate from Melmac.

./kate.earth.php
<?php
require_once("alf.home.php");
/*
* 但是如果我们想纠正凯特的起源?
* 如何在注册时将参数传递给自动加载函数?
*
* spl_autoload_register 不适合这样做
* 但我们可以尝试在注册期间定义一个可调用对象
*/
spl_autoload_register(function($class){
call_user_func(array(new ALF(),'haaahaaahaaa'), $class, "Earth"); });
/*
* 现在再次尝试自动加载一个类
* Kate 仍然找不到,但我们修正了她的起源 :)
*/
@$kate = new Kate(); // Kate 来自地球 :)
/*
* 注意:你不能使用上面的注册方式传递 $this 或在可调用对象上下文中创建的其他对象。因此,你应该将你的自动加载函数替换为像 ALF 一样在开头定义的单独类。
*
* 注意:你可能无法直接注销你的自动加载函数,因为一个实例是在另一个上下文中创建的
*/
?>
I am Kate from Earth.
0
Daniel Klein
2 年前
如果你希望能够从任何地方运行你的 PHP 脚本,而无需首先更改目录,请在第一个运行的文件(而不是任何包含的文件)中使用 chdir(__DIR__)

<?php
spl_autoload_register
();
chdir(__DIR__);

出于
某种原因尝试在其他命名空间类中使用命名空间类会导致失败

例如运行 "php src/main.php" 将失败"cd src && php main.php" 将起作用

src/main.php
<?php
spl_autoload_register
();
//chdir(__DIR__); // 取消注释以使其从任何目录工作
MyNamespace\MyClass::foo();

src/MyNamespace/MyClass.php
<?php
namespace MyNamespace;

class
MyClass {
public static function
foo(): void {
echo
MyOtherClass::BAR; // 即使 MyOtherClass.php 在正确的位置,这也将失败
}
}

src/MyNamespace/MyOtherClass.php
<?php
namespace MyNamespace;

class
MyOtherClass {
public const
BAR = 'baz';
}
1
stanlemon at mac dot com
16 年前
编者按:此函数模拟的行为所请求的适当 PHP 错误是 http://bugs.php.net/bug.php?id=42823 。如果在自动加载堆栈中注册了数组($obj,'nonStaticMethod'),则此函数不起作用——虽然自动加载将被删除,但它将被错误地重新注册。

spl_autoload_register() 方法按 spl_autoload_register() 被调用的顺序在其堆栈中注册函数,因此,如果您希望自动加载函数覆盖以前的自动加载函数,则需要注销以前的函数或更改自动加载堆栈的顺序。

例如,假设在自动加载函数的默认实现中,如果找不到类,则抛出异常,或者可能抛出致命错误。稍后在您的代码中,您添加了自动加载函数的第二个实现,该实现将加载第一个方法会失败的库。这不会首先调用第二个自动加载器方法,而是会继续在第一个方法上出错。

如前所述,您可以注销出错的现有自动加载器,也可以创建注销和重新注册自动加载器的机制,以您想要的顺序执行。

以下是如何考虑重新注册自动加载器的示例/示例,以便最新的自动加载器首先被调用,而最旧的自动加载器最后被调用

<?php

// 编辑说明:在函数中添加了小的错误和兼容性修复
// 添加到函数

function spl_autoload_preregister( $autoload ) {
// 堆栈中目前没有函数。
if ( ($funcs = spl_autoload_functions()) === false ) {
spl_autoload_register($autoload);
} else {
// 注销现有的自动加载器...
$compat =
version_compare(PHP_VERSION, '5.1.2', '<=') &&
version_compare(PHP_VERSION, '5.1.0', '>=');
foreach (
$funcs as $func) {
if (
is_array($func)) {
// :TRICKY: 存在一些兼容性问题,并且在一些情况下我们需要报错
// 地方,我们需要报错
$reflector = new ReflectionMethod($func[0], $func[1]);
if (!
$reflector->isStatic()) {
throw new
Exception('
此函数与非静态对象方法不兼容
由于 PHP 错误 #44144。
'
);
}
// 令人惊讶的是,spl_autoload_register 支持
// Class::staticMethod 回调格式,虽然 call_user_func 不支持
if ($compat) $func = implode('::', $func);
}
spl_autoload_unregister($func);
}

// 注册新函数,将其置于堆栈顶端...
spl_autoload_register($autoload);

// 现在,返回并重新注册我们所有的旧函数。
foreach ($funcs as $func) {
spl_autoload_register($func);
}
}
}

?>

注意:我没有测试过它的开销,因此我不确定上述示例的性能影响。
0
n0mAd at example dot com
6 年前
如果您需要在使用命名空间时注册函数,请使用 __NAMESPACE__ 常量来定义名称。

<?php

namespace Foobar;

spl_autoload_register('MyFunction'); // 不正确
spl_autoload_register('\MyFunction');// 不正确
spl_autoload_register(__NAMESPACE__ . '\MyFunction'); // 正确

?>
0
harvey dot NO_SPAM dot robin at gmail dot com
17 年前
此函数足够智能,不会添加两次相同的加载器。这似乎适用于所有不同的加载器格式。示例

<?php
class ALoader
{
static function
load($class) { return true; }
}

function
anotherLoader($class) {
return
true;
}

$F = new ALoader;

spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array($F, 'load'));
spl_autoload_register('anotherLoader');
spl_autoload_register('anotherLoader');
var_dump(spl_autoload_functions());

/*
* PHP5.2 CLI 上的结果,Linux。
* array(2) {
* [0]=>
* array(2) {
* [0]=>
* string(7) "ALoader"
* [1]=>
* string(4) "load"
* }
* [1]=>
* string(13) "anotherLoader"
* }
*/
?>
-1
hajo-p
10 年前
如果您有像 "/abc/def/ghi" 这样的目录结构,您的 index.php 位于顶层目录中,但您希望使用以 "def" 或 "ghi" 开头的命名空间

您可以使用例如 set_include_path(__DIR__ . '/abc') 切换 PHP 的命名空间根目录,然后使用简单的 spl_autoload_register() 函数定义和使用命名空间,而无需提供任何参数。

请记住,PHP 处理程序 "cli" 和 "cli-server" 是特殊情况。
-1
joneschrisan at aol dot com
8 年前
看起来在 Debian PHP 的最新更新中,在 Linux 上,对 spl_autoload 不传递任何参数不再起作用。

它无法将命名空间中的 \'s 替换为文件路径中的 /'s。
-3
Kurd the Great
10 年前
if(!defined('BASE_PATH')) {
define('BASE_PATH', dirname(__FILE__) . '/');
require BASE_PATH . 'Autoloader.php';
Autoloader::Register();
}

class Autoloader
{
public static function Register() {
return spl_autoload_register(array('Autoloader', 'Load'));
}

public static function Load($strObjectName) {
if(class_exists($strObjectName) === false) {
return false;
}

$strObjectFilePath = BASE_PATH . $strObjectName . '.php';

if((file_exists($strObjectFilePath) === false) || (is_readable($strObjectFilePath) === false)) {
return false;
}

require($strObjectFilePath);
}
}
-2
neolium at gmail dot com
9 年前
此自动加载将找到您调用的每个类,如果您将每个类放在不同的文件中。

它从您在 $root 变量中指定的根目录递归地进入每个目录。

您可以在 $dir_to_not_look_in 数组中指定您不想遍历的文件夹(例如,您不会在 MVC 项目的“view”文件夹中找到任何类);

spl_autoload_register(function($class) {

$root = 'my/root/path';
$file = $class . '.php';
$dir_to_not_look_in = array($directories, $to, $not, $look, $in);

if(!function_exists('load')) {
function load($dir, $file) {
if(file_exists($dir . '/' . $file)) {
require_once $dir . '/' . $file;
} else {
foreach(scandir($dir) as $value) {
if(is_dir($dir. '/' . $value) && !in_array($value, $dir_to_no_look_in))
load($dir. '/' . $value, $file);
}
}
};
}

load($root, $file);

});
-5
nmmm at nmmm dot nu
10 年前
可以使用 `spl_autoload_register()` 与 `include_path`。

假设在当前目录下有一个目录名为 “a”, 其中包含一个名为 “test” 的目录, 并在该目录下有一个名为 “test.php” 的文件

<?
namespace test;
class test{
function __construct(){
echo "Test created\n";
}
}
?>

那么可以使用以下代码加载该类
<?
ini_set("include_path", "./a/");

spl_autoload_register();

$t = new \test\test();
?>
-4
xavier dot bouhours at free dot fr
9 年前
// 获取最新版本的类

if( !function_exists('classAutoLoader') )
{
function classAutoLoader($className)
{
$classFiles = array() ;
$classFile = FALSE ;
$classDir = __DIR__ .'/' ;
// 获取所有文件
$files = scandir( $classDir ) ;
foreach ( $files as $url )
{
// 验证文件是否为:名称 + 类名 + 版本 + 扩展名
if( is_file($classDir.$url) && preg_match('/([^\.]+)\.class\.([\d\.]+)\.(.+)$/', $url, $m ) )
{
// 验证找到的文件
if( $className == $m[1] )
{
// 获取之前的版本或初始化
$previous = isset( $classFiles[$m[1]] ) ? $classFiles[$m[1]] : 0 ;

// 获取最新版本
if( $previous<$m[2] )
{
$classFiles[ $m[1] ] = $m[2] ; // 版本
$classFile = $classDir.$url ;
}
}
}
} ;
if( !class_exists($className) ) include( $classFile );
}
}
spl_autoload_register('classAutoLoader') ;
-5
sebastian at 34n dot de
11 年前
你也可以这样使用它

> spl_autoload_register ( array( new AutoloaderClass, 'method') );

或者在 PHP > 5.3 中

> spl_autoload_register ( [ new My\Namespace\Autoloader, 'method'] );

通过这种方式,你不需要创建一个只使用一次的变量。
-12
ali dot taheri dot m at gmail dot com
11 年前
我写了一个小函数,可以创建和注册一个加载器,这个加载器似乎安全可靠,虽然我不确定,但我觉得分享是一个好主意,我花了一些时间才想出来,我希望它能节省一些人的时间。

<?php

function Loader($root = "") {
$loaderFunction = create_function('$class', 'include "' . $root . '$class.php";');
spl_autoload_register($loaderFunction);
}

?>

如果你有一个文件系统,其结构与你的目录树完全相同,那么这个函数可以完美地工作。我还没有在 Unix 上测试它,但在 Windows 上,当你的网页不在根目录下时,默认的加载器会失败。这个函数确保即使你的网页在子目录下也不会出现问题,只需将 `../` 或更多驱动程序 `../../` 作为根目录传递,它就会像魅力一样工作。请注意,我无法使用匿名函数,因为 `$root` 变量将不会与 `Loader` 函数具有相同的范围,因此必须动态创建该函数。这是一个很好的示例,说明了该函数的使用方法。

你的类
root/classes/support/classic.php
<?php

namespace classes/support;

class
classic {
// class def
}

?>

root/support/index.php
<?php

Loader
('../');

use
classes/support/classic;

$cls = new classic();
//use $cls
?>

加载器将生成一个类似于以下代码的函数
<?php

function($class) {
include
"../$class.php";
}

//当需要该类时,将运行该脚本,这正是我们需要的:

include '../classes/support/classic.php';

?>

希望这能帮到大家。
-36
Anonymous
12 年前
请注意,当指定第三个参数(前缀)时,该函数在 PHP 5.2 中将严重失败。
To Top