Php spl_自动加载_寄存器加载类两次
我一直试图知道这个非常简单的类装入器脚本的问题是什么。 类装入器如下所示:Php spl_自动加载_寄存器加载类两次,php,autoload,spl-autoload-register,Php,Autoload,Spl Autoload Register,我一直试图知道这个非常简单的类装入器脚本的问题是什么。 类装入器如下所示: #src/vendors/Autoloading/lib/ClassLoader.php namespace App\Vendors\Autoloading; class ClassLoader { private $path; function __construct($path) { $this->path = $path; }
#src/vendors/Autoloading/lib/ClassLoader.php
namespace App\Vendors\Autoloading;
class ClassLoader
{
private $path;
function __construct($path)
{
$this->path = $path;
}
public function load($class)
{
if(file_exists( $class = str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $this->path) . '.php')){
require $class;
return true;
}
}
public function register()
{
return spl_autoload_register([$this, 'load']);
}
}
最初的类加载器有更多的方法和一些函数来验证文件名。。。
但是,在调试的过程中,我不得不把范围缩小到这个范围
因此,在autoload.php
文件中需要该类加载器,如下所示
#src/vendors/autoload.php
namespace App\Vendors;
require 'Autoloading/lib/ClassLoader.php';
$autoload = new Autoloading\ClassLoader('path/Foo/FooClass');
$autoload->register();
FooClass.php
位于src/Foo/FooClass.php
namespace App\Foo;
class FooClass{}
自动加载部分实际上没有问题,类加载得很好,但是它执行了两次,这显示了下面的错误。我从index.php
文件调用它
<?php
use \App\Foo\FooClass;
FooClass::somefunction();
尝试使用require\u一次
而不是require
。你的自动加载器不会跟踪到目前为止已加载的文件
下面是我如何设置我的。我不用上课。也许这会有帮助
function PlatformAutoloader($classname) {
try {
// Change \ to / so namespacing will work
$classname = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $classname));
if(!@include_once(DIR_CLASSES . DIRECTORY_SEPARATOR . $classname . '.php')) return false;
} catch(Exception $e) {
return false;
}
}
spl_autoload_register('PlatformAutoloader');
尝试使用require\u一次,而不是require
。你的自动加载器不会跟踪到目前为止已加载的文件
下面是我如何设置我的。我不用上课。也许这会有帮助
function PlatformAutoloader($classname) {
try {
// Change \ to / so namespacing will work
$classname = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $classname));
if(!@include_once(DIR_CLASSES . DIRECTORY_SEPARATOR . $classname . '.php')) return false;
} catch(Exception $e) {
return false;
}
}
spl_autoload_register('PlatformAutoloader');
在检查文件之前,请使用检查类是否已存在。在检查文件之前,请使用检查类是否已存在。您的自动加载功能错误:
public function load($class)
{
if (
file_exists(
$class = str_replace(
array('\\', '_'),
DIRECTORY_SEPARATOR,
$this->path)
. '.php')
) {
require $class;
return true;
}
}
使用要加载的类的名称调用函数(如果不可能,函数不应执行任何操作)
您要做的是忽略类名,并根据创建自动加载程序的路径创建一个新的类名。这将始终加载具有相同类的相同文件,即使要加载的类不同
这就解释了为什么会出现错误,因为无论传递哪个类名,都会包含一个与路径相关的文件
您可能需要使用合适的PSR-0或PSR-4自动加载器。我建议您使用Composer附带的,因为您可能迟早会自己使用Composer。为什么不从今天开始?您的自动加载功能错误:
public function load($class)
{
if (
file_exists(
$class = str_replace(
array('\\', '_'),
DIRECTORY_SEPARATOR,
$this->path)
. '.php')
) {
require $class;
return true;
}
}
使用要加载的类的名称调用函数(如果不可能,函数不应执行任何操作)
您要做的是忽略类名,并根据创建自动加载程序的路径创建一个新的类名。这将始终加载具有相同类的相同文件,即使要加载的类不同
这就解释了为什么会出现错误,因为无论传递哪个类名,都会包含一个与路径相关的文件
您可能需要使用合适的PSR-0或PSR-4自动加载器。我建议您使用Composer附带的,因为您可能迟早会自己使用Composer。为什么不从今天开始?如果类已经存在,自动加载器不应该被触发两次,是吗?@Mark Baker。这是我做的第一件事。我100%是自动加载两次如果类已经存在,自动加载程序不应该被触发两次,是吗?@markbaker。这是我做的第一件事。我100%是自动加载两次自动加载不应该为同一类触发两次。不。这一点都没有改变。你希望发现什么样的异常?是否调用了任何抛出异常的PHP内部函数?@Sven否。实际上,正如问题中所述。为了调试它,我隔离了这个类加载器。所以,你可以说,我只有类加载器,类和索引文件来实例化这个类。我认为这是我们过去抛出错误时留下的痕迹。您可以安全地忽略它。自动加载器不应该为同一类触发两次。不。这一点都没有改变。你希望发现什么样的异常?是否调用了任何抛出异常的PHP内部函数?@Sven否。实际上,正如问题中所述。为了调试它,我隔离了这个类加载器。所以,你可以说,我只有类加载器,类和索引文件来实例化这个类。我认为这是我们过去抛出错误时留下的痕迹。你可以放心地忽略它。谢谢,但我仍然得到同样的错误。我一定是做错了什么。你能告诉我你将如何至少实例化类加载器吗?你改变了什么?“仍然”意味着你改变了一些东西,“仍然”不起作用。您应该使用$class变量,添加路径,将类名转换为另一个路径,在末尾添加“.php”,并需要该文件(如果存在)。不要改变$class,创建一个新的$filename。我已经做到了,相信我。我不是在骗你,我只是花了几个小时想弄明白。我知道,不能重新声明类
文件您当前的代码就是我在您的问题中看到的代码吗?那么,我在回答中所描述的方式仍然是错误的。请注意,我在回答中没有修复您的代码,我只是引用并重新格式化了它。我注意到,您的类名为\App\Foo\FooClass
,但错误消息抱怨正在重新声明path\Foo\FooClass
。为什么会这样?谢谢,但我还是会犯同样的错误。我一定是做错了什么。你能告诉我你将如何至少实例化类加载器吗?你改变了什么?“仍然”意味着你改变了一些东西,“仍然”不起作用。您应该使用$class变量,添加路径,将类名转换为另一个路径,在末尾添加“.php”,并需要该文件(如果存在)。不要改变$class,创建一个新的$filename。我已经做到了,相信我。我不是在骗你,我只是花了几个小时想弄明白。我知道,不能重新声明类
文件您当前的代码就是我在您的问题中看到的代码吗?那么,我在回答中所描述的方式仍然是错误的。请注意,我没有在中修复您的代码