【问题标题】:PHP autoloader with namespaces [duplicate]带有命名空间的PHP自动加载器[重复]
【发布时间】:2014-09-21 10:27:00
【问题描述】:

我正在尝试了解如何为带有命名空间的普通应用程序定义一个有效的自动加载器。

我创建了以下结构:

public
    index.php
src
    Models
        WordGenerator.php

显然,以后它会增长。 WordGenerator.php 文件如下:

<?php
namespace Models;

class WordGenerator {
    public $filename;

    public function __construct($filename) {
        $this->_filename = $filename;
    }
}

现在我尝试在index.php 中创建这个对象的实例:

<?php
use \Models;

$wg = new WordGenerator("words.english");

显然我得到了致命错误,因为我没有定义autoloader。但是,根据文档,我只能通过$classname。那么我应该如何定义自动加载器函数来获取use声明的命名空间呢??

[编辑] 刚才我理解错了。所以这是我的index.php 代码:

spl_autoload_register(function ($className) {
    $className = ltrim($className, '\\');
    $prepend = "..\\src\\";
    $fileName  = "{$prepend}";
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = $prepend.str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

    require $fileName;
});
//require '../src/Models/WordGenerator.php';

use Models;

$wg = new WordGenerator("words.english");
echo $wg->getRandomWord();

现在,这不起作用,我得到:

Warning: The use statement with non-compound name 'Models' has no effect in C:\xampp\htdocs\Hangman\public\index.php on line 22

Warning: require(..\src\WordGenerator.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Hangman\public\index.php on line 16

Fatal error: require(): Failed opening required '..\src\WordGenerator.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\Hangman\public\index.php on line 16

但是,当我将 new WordGenerator 更改为 new \Models\WordGenerator 时,它可以工作。现在的问题是:如何将 use 语句声明的命名空间传递给 autoloader 函数以使其正常工作?

【问题讨论】:

    标签: php namespaces php-5.3 spl-autoload-register


    【解决方案1】:

    您的use 声明不正确。你要use Models\WordGenerator;

    use 操作符只声明一个别名。考虑扩展形式:

    use Models\WordGenerator as WordGenerator;
    

    这是等价的。


    可以为命名空间而不是类起别名,但它不能以您尝试的方式工作。例如:

    use Models as Foo;
    $wg = new Foo\WordGenerator("words.english");
    

    会工作的。然而:

    use Models;
    

    相当于:

    use Models as Models;
    

    实际上什么都不做。


    有关更多信息,请参阅 PHP 手册中的Using namespaces: Aliasing/Importing

    【讨论】:

    • 我不能像在 C++ 中那样使用整个命名空间吗?
    【解决方案2】:

    请看documentation。 Autoloader 必须由您在脚本开始时定义。在提供的链接中有示例自动加载器和更复杂的solution

    【讨论】:

      猜你喜欢
      • 2021-04-04
      • 2013-10-24
      • 2013-11-25
      • 2014-04-13
      • 2014-07-02
      • 2011-08-06
      • 2015-07-15
      相关资源
      最近更新 更多