【问题标题】:PHP Namespacing errorPHP命名空间错误
【发布时间】:2017-07-10 13:18:36
【问题描述】:

我将首先展示我的代码,为了学习,我尽量保持简单。

我的代码

index.php -

require('autoloader.php');

$hammer = new Acme\Tools\Hammer();

autoloader.php -

spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

Hammer.php -

namespace Acme\Tools;

class Hammer
{

    public function useTool()
    {
        echo 'You start using the hammer!';
    }

}

我的问题/错误信息

警告:包括(Acme\Tools\Hammer.php):无法打开流:否 第 4 行 C:\xampp\htdocs\php\autoloader.php 中的此类文件或目录

警告:include():无法打开“Acme\Tools\Hammer.php” 包含(include_path='C:\xampp\php\PEAR') C:\xampp\htdocs\php\autoloader.php 在第 4 行

致命错误:未捕获的错误:找不到类“Acme\Tools\Hammer” C:\xampp\htdocs\php\index.php:5 堆栈跟踪:#0 {main} 抛出 C:\xampp\htdocs\php\index.php 在第 5 行

我最初在 index 中使用 'use' 语句,如下所示,但改变了它认为它会有所帮助。

旧 index.php -

use Acme\Tools;

require('autoloader.php');

$hammer = new Tools\Hammer();

有谁知道为什么两者都不起作用?

【问题讨论】:

  • 短语No such file or directory有什么不清楚的地方?
  • 你把 Hammer.php 放在哪里了?
  • @IvoP 都在同一个目录中
  • @u_mulder 我可以阅读,但就像我说的我不确定错误是什么,我也是命名空间和自动加载的新手,你可以想象,一切都在同一个目录中。但我认为它试图自动加载命名空间目录。我不知道如何让它拉一个命名空间目录。

标签: php


【解决方案1】:

您的自动加载器假定完整的类名是类文件的完整路径。您需要在它前面加上类路径的根目录。 __DIR__ 在此示例中假定类路径从运行脚本的位置开始,但您需要更改它以反映正确的路径:

spl_autoload_register(function ($class_name) {
    include __DIR__ . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class_name) . '.php';
});

这是一个非常原始的自动加载器示例。如果您想使用当前建立的自动加载方法,请对Composer进行一些研究。

【讨论】:

  • 作曲家+1。当有诸如 Composer 之类的已建立的东西可以以更好的方式处理此问题时,您可能不需要已经必须执行自动加载的代码。
  • 但如果我不懂自动加载,我为什么要深入作曲家自动加载?
  • @YasminFrench 这很好,它更高级,你需要在深入研究它之前了解自动加载的工作原理,因为 Composer 有自己的头痛。但这就是您的目标进展路径,上面的代码应该可以解决您当前的问题。
  • @Flosculus 谢谢,我用过这个但仍然得到同样的错误。我认为它的原因是寻找命名空间目录?
  • 我想你可能会,如果你按原样使用它,但我不知道你的目录结构是什么样的。
【解决方案2】:

当所有人都在同一个目录中时: 剥离整个名称空间

spl_autoload_register(function ($class_name) {
    $file = preg_match('#[^\\](.*)$#', $class_name, $a);
    include $a[1] . '.php';
});

如果将文件放在 /acme/Tools/Hammer.php 中会更有意义

【讨论】:

  • 假设在项目的整个生命周期中文件结构将保持不变。最好一开始就包含格式良好的包含(DIR)。
  • 是的,结构将保持不变。否则,您必须相应地更改自动加载器。该函数旨在使用某种逻辑查找脚本。命名空间通常是该逻辑的一部分
【解决方案3】:

只是上面@Flosculus 答案的一个小补充:

/**
 *    our register function :
 *    requires that anything that is 'name spaceable' be in a
 *      php file, one per item.
 *
 *    requires that the directory structure matches EXACTLY (case)
 *      the namespace requirement.
 *
 */

spl_autoload_register(
    function ($name) {
        $name = str_replace("\\" , DIRECTORY_SEPARATOR , $name);
        $fqn  = __DIR__ . "/" . $name . ".php";
        /** @noinspection PhpIncludeInspection */
        require_once $fqn;

    }
);

当中断时,这就是我在调试会话窗口中得到的结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2013-06-17
    • 2012-10-24
    • 1970-01-01
    相关资源
    最近更新 更多