自动加载
每次使用类或继承时,没有人想要 require
或 include
。因为它可能很痛苦并且容易忘记,所以 PHP 提供了所谓的自动加载。如果你已经在使用 Composer,请阅读使用 Composer 进行自动加载的内容 。
什么是自动加载?
这个名字基本上都说明了一切。你没有得到所请求的类存储在文件中,但 PHP 自动 matically 负荷这样。
如何在没有第三方代码的基本 PHP 中执行此操作?
有 __autoload
的功能,但使用 spl_autoload_register
被认为是更好的做法。每次在给定空间内未定义类时,PHP 都会考虑这些函数。因此,将 autoload 添加到现有项目是没有问题的,因为定义的类(通过 require
ie)将像以前一样工作。为了准确起见,以下示例将使用匿名函数,如果使用 PHP <5.3,则可以定义函数并将其名称作为参数传递给 spl_autoload_register
。
例子
spl_autoload_register(function ($className) {
$path = sprintf('%s.php', $className);
if (file_exists($path)) {
include $path;
} else {
// file not found
}
});
上面的代码只是尝试使用 sprintf
包含一个带有类名的文件名和附加的扩展名“.php” 。如果需要加载 FooBar
,它看起来是否存在 FooBar.php
,如果包含它。
当然,这可以扩展到适合项目的个人需求。如果类名中的 _
用于分组,例如 User_Post
和 User_Image
都引用 User
,则两个类都可以保存在名为 User
的文件夹中,如下所示:
spl_autoload_register(function ($className) {
// replace _ by / or \ (depending on OS)
$path = sprintf('%s.php', str_replace('_', DIRECTORY_SEPARATOR, $className) );
if (file_exists($path)) {
include $path;
} else {
// file not found
}
});
类 User_Post
现在将从“User / Post.php”等加载。
spl_autoload_register
可根据不同需求量身定制。所有带有类的文件都被命名为“class.CLASSNAME.php”?没问题。各种嵌套(User_Post_Content
=>“User / Post / Content.php”)?没问题。
如果你想要更复杂的自动加载机制 - 并且仍然不想包含 Composer - 你可以在不添加第三方库的情况下工作。
spl_autoload_register(function ($className) {
$path = sprintf('%1$s%2$s%3$s.php',
// %1$s: get absolute path
realpath(dirname(__FILE__)),
// %2$s: / or \ (depending on OS)
DIRECTORY_SEPARATOR,
// %3$s: don't wory about caps or not when creating the files
strtolower(
// replace _ by / or \ (depending on OS)
str_replace('_', DIRECTORY_SEPARATOR, $className)
)
);
if (file_exists($path)) {
include $path;
} else {
throw new Exception(
sprintf('Class with name %1$s not found. Looked in %2$s.',
$className,
$path
)
);
}
});
使用这样的自动加载器,你可以愉快地编写如下代码:
require_once './autoload.php'; // where spl_autoload_register is defined
$foo = new Foo_Bar(new Hello_World());
使用类:
class Foo_Bar extends Foo {}
class Hello_World implements Demo_Classes {}
这些例子将包括 foo/bar.php
,foo.php
,hello/world.php
和 demo/classes.php
的类。