我想一起使用namespace和spl_autoload_register,但每次都失败并出现不同的错误。
请参阅github上的完整代码文件。
以下是文件
class.alpha.php
include.php
eg.php
现在,当我从 eg.php
创建对象时,它会产生致命错误,但当我在 class.alpha.php
中评论命名空间行时,它就会出现问题。工作
请参阅以下代码。
<?php
//namespace Alpha; //<< comment and uncomment this to regenerate the error
class Alpha
{
// public static $baseDir_;
public $dir = __DIR__;
public static $baseDir_;
public function __construct()
{
echo __FILE__."=>".__METHOD__;
var_dump(self::$baseDir_, $this->dir);
$firstDir = !empty(self::$baseDir_) ? self::$baseDir_ : $this->dir;
}
}
<?php //namespace Alpha\config;
spl_autoload_extensions(".php");
spl_autoload_register('loadclass');
function loadclass($class)
{
try {
if (is_readable(strtolower($class).".class.php")) {
include_once strtolower($class).".class.php";
}
} catch (Exception $e) {
print "Exception:". $e;
}
}
//@link http://php.net/manual/en/function.spl-autoload-register.php
// spl_autoload_register(__NAMESPACE__.'Alpha\Alpha()' );
<?php
require_once 'include.php';
/** below code works by commenting 1st line on alpha.class.php
if we un comment then below code gives Fatal error: Class 'Alpha' not found */
Alpha::$baseDir_ = '/opt/lampp/archive/';
$obj_ = new Alpha();
var_dump(get_included_files());
var_dump($obj_);
/** now we define namespace Alpha on alpha.class.php */
// $ns_ = new Alpha\Alpha(); // Fatal error: Class 'Alpha\Alpha' not found
// var_dump($ns_);
/** not working even with use statement */
// use Alpha;
// use Alpha;
// $fn = new Alpha\Alpha();
// var_dump($fn);
请帮我解决这个问题。
由于
答案 0 :(得分:1)
如果您取消注释alpha.class.php
中的命名空间并将use Alpha\Alpha
放入例如,您的自动装带器将收到“Alpha \ Alpha”类的请求。这意味着它希望找到您班级的位置为alpha\alpha.class.php
。
除非您使用的是Windows,否则目录分隔符通常是正斜杠(/)。所以有很多可能的解决方案。
**可能的解决方案#1 - 将所有文件保留在同一个地方**
如果要将所有内容保留在现在的位置,则需要从自动装带器中的类名中删除命名空间。如果将这些行添加到自动装带器的顶部,则会使其表现如下:
$classParts = explode("\\", $class);
$class = $classParts[count($classParts) - 1];
我不建议使用此解决方案,因为这意味着您不能再在不同的命名空间中提供相同的类名。
可能的解决方案#2 - 将名称空间放在子目录中
对于此解决方案,您将创建一个新目录“alpha”并将“alpha.class.php”移入其中。对于自动装带器更改,您可以将以下行添加到自动装带器的顶部:
$class = str_replace("\\", "/", $class);
这会使用正斜杠将命名空间分隔符从反斜杠更改为文件路径分隔符。这将适用于Windows以及Mac和Linux。
可能的解决方案#3 - 遵循既定的自动加载标准
已经有许多标准的PHP自动加载标准。 PSR-0(现已弃用)有效,但建议使用PSR-4:
遵循其中一个标准的一个重大优点是已经有很多实现它们,并且已经有很多想法应该如何工作并保持与您可能最终想要使用的其他库的兼容性。 Composer(http://getcomposer.org)允许您根据非常简单的配置设置和使用PSR-0和PSR-4样式的自动加载器。
无论如何,对于TL; DR众人,问题是自动加载器接收整个命名空间路径以便知道如何加载类。致命错误是因为自动加载器没有正确地从该命名空间类映射到文件系统位置,因此从未加载包含该类的文件。
希望这有帮助。