我正在学习高级PHP标准,并尝试实现新的有用方法。之前,我__autoload
只是为了转义而在每个页面上包含多个文件,但是最近我看到了一个提示__autoload manual
spl_autoload_register()为自动加载类提供了更灵活的替代方法。因此,不建议使用__autoload(),以后可能不建议使用或将其删除。
但我真的不知道如何实施spl_autoload
和spl_autoload_register
我正在学习高级PHP标准,并尝试实现新的有用方法。之前,我__autoload
只是为了转义而在每个页面上包含多个文件,但是最近我看到了一个提示__autoload manual
spl_autoload_register()为自动加载类提供了更灵活的替代方法。因此,不建议使用__autoload(),以后可能不建议使用或将其删除。
但我真的不知道如何实施spl_autoload
和spl_autoload_register
Answers:
spl_autoload_register()
允许您注册PHP将放入堆栈/队列中的多个函数(或您自己的Autoload类中的静态方法),并在声明“新类”时顺序调用。
因此,例如:
spl_autoload_register('myAutoloader');
function myAutoloader($className)
{
$path = '/path/to/class/';
include $path.$className.'.php';
}
//-------------------------------------
$myClass = new MyClass();
在上面的示例中,“ MyClass”是您要实例化的类的名称,PHP将该名称作为字符串传递给spl_autoload_register()
,从而允许您选择变量并将其用于“包含”适当的类/文件。因此,您不需要特别通过include / require语句来包含该类。
就像上面的示例一样,只需简单地调用您想要实例化的类,并且由于您注册了spl_autoload_register()
自己的函数(通过)即可确定所有类的位置,因此PHP将使用该函数。
使用的好处spl_autoload_register()
是,与__autoload()
您不同的是,您不需要在创建的每个文件中实现自动加载功能。spl_autoload_register()
还可以让您注册多个自动加载功能,以加快自动加载并使其更加容易。
例:
spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');
class MyAutoloader
{
public static function ClassLoader($className)
{
//your loading logic here
}
public static function LibraryLoader($className)
{
//your loading logic here
}
关于spl_autoload,手册指出:
该功能旨在用作的默认实现
__autoload()
。如果未指定其他内容且spl_autoload_register()
没有任何参数调用该函数,则此函数将用于以后对的任何调用__autoload()
。
实际上,如果所有文件都位于一个目录中,并且您的应用程序不仅使用.php文件,而且还使用扩展名为.inc的自定义配置文件,那么您可以使用的一种策略是添加包含所有内容的目录文件到PHP的包含路径(通过set_include_path()
)。
而且,由于还需要配置文件,因此将用于spl_autoload_extensions()
列出要PHP查找的扩展名。
例:
set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();
由于spl_autoload是__autoload()
magic方法的默认实现,因此当您尝试实例化新类时,PHP将调用spl_autoload。
希望这可以帮助...
spl_autoload_register()
__autoload()
从PHP 5.3开始,您可以使用spl_autoload_register()
名称空间,这意味着您可以组织项目并自动加载php类,而无需任何要求或包含,也无需重新定义__autoload()
函数。
为了演示这种行为,只需创建一个名为index.php的文件:
<?php
spl_autoload_register();
var_dump(new Main\Application);
然后在index.php文件旁边创建一个名为Main的文件夹。最后,在Main中创建一个名为Application.php的文件,并将以下代码粘贴到其中:
<?php namespace Main;
class Application{}
spl_autoload_register()
默认实现无法找到继承的类。因此,使用默认值,小写的文件和反映名称空间路径的目录,除非我拥有扩展另一个类(父类)的类,否则一切都可以正常工作。然后,PHP引发错误,即使它们都在同一目录/名称空间中,也找不到该父类!令人困惑的是,实际上只能找到一级类,因此我不得不spl_autoload_register()
在第一个类之后放置另一个具有匿名函数规则的类,以便手动包括丢失的父类/继承的类。
这是我使用自动加载的方式。在给定的示例中,我希望从3个不同的目录中加载类。
function namespaceAutoload($rawClass){
$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);
$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';
foreach ($possiblePaths as $templatePath) {
$path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
if (file_exists($path)) {
require_once "$path";
break;
}
} spl_autoload_register("namespaceAutoload");
在给定的示例中,PHP将使用这三种不同的文件名格式在这三个目录中查找namespace \ class。