默认 spl_autoload_register() 命名空间行为 index.php 在 root 之外

default spl_autoload_register() namespace behavior with index.php outside root

使用现代 PHP,调用

spl_autoload_register();

允许您实例化新的 classes 而无需在 php 文件中指定 REQUIRE、INCLUDE 或 USE,只要它们有一个命名空间,并且只要该命名空间遵循folder/file结构如:

|--models
     |-- utility
|           |___calculator.php
|
|
|--index.php

使用这样的设置,如果 calculator.php 已在其顶部声明 "namespace models\utility",并且它包含 class 计算器(与文件名 calculator.php 匹配),您可以通过调用 index.php 自动实例化它:

calc = New models\utility\Calculator();

但是,如果文件夹结构是这样的:

|--models
     |-- utility
|           |___calculator.php
|
|
|--public
     |--index.php

现在 index.php 无法再通过其命名空间访问计算器,因为 index.php 不再位于根文件夹中。

public/index.php 似乎无法访问其级别以上的命名空间。这只是PHP的限制。有没有一种方法可以使用 spl_autoload_register 注册一个函数,该函数将保留其自动、易于处理的行为,但允许 index.php 在其文件夹级别之上实例化名称空间?或者另一种处理这种情况的方法,同时仍然不必使用或 REQUIRE/INCLUDE 文件?


更新答案

这是一个对我有用的与目录无关的解决方案。我可以仅通过调用它们的命名空间来成功实例化新的 classes,而不必求助于 USE、REQUIRE 或 INCLUDE,即使 index.php 已移至 /public 文件夹。

//'/../../../../' points the autoloader.php file back to root directory
$include_path = realpath(dirname(__FILE__) . '/../../../../');         
set_include_path($include_path);
spl_autoload_register();

使用spl_autoload_register() function is called without the $autoload_function argument, the default autoloading function spl_autoload()时。

文件的 spl_autoload() function checks all include paths,将命名空间与文件夹匹配,class 名称与文件匹配,正如您已经注意到的那样。

你的关键是确保包含你的 class 文件的目录结构的文件夹(即包含 models 的目录)在包含路径上。这通常使用 set_include_path() 函数完成。