【问题标题】:Namespaced autoloading not working properly命名空间自动加载无法正常工作
【发布时间】:2015-10-07 09:52:22
【问题描述】:

我无法让自动加载与命名空间一起使用。这是我为此创建的目录结构:

index.php
app/
  utils/
    sys/
      DirReader.php
    helpers/
      DB.php

index.php 包含自动加载器,其中包括文件 DirReader.php 和 DB.php。

index.php 是这样的:

<?php

function __autoload($ns_str) //ns_str = namespace string
{
    $path = str_replace('\\', DIRECTORY_SEPARATOR, $ns_str);
    //echo "**$path**\n";
    require_once "$path.php";
}

use \app\utils\sys as sys;
use \app\utils\helpers as helpers;

$dir = new sys\DirReader();
$db = new helpers\DB();

这里是DirReader.php

<?php
namespace app\utils\sys;

class DirReader
{
    public function __construct()
    {   
        echo "DirReader object created!\n";
    }   
}

这里是DB.php

<?php
namespace app\utils\helpers;

class DB
{
    public function __construct()
    {   
        echo "DB object created!\n";
    }   
}

该示例运行良好,但是当我向index.php 添加命名空间声明时,它失败了:

<?php
    namespace myns;
    function __autoload($ns_str) //ns_str = namespace string
    { /*. . .*/

PHP 致命错误:在中找不到类 'app\utils\sys\DirReader' /var/www/html/php_learn/autoloading_1/index.php 第 15 行 PHP 堆栈 跟踪:PHP 1. {main}() /var/www/html/php_learn/autoloading_1/index.php:0

在我看来,这个错误不应该出现,因为我在 index.php 中使用命名空间时使用了绝对名称。我知道说像use app\utils\sys as sys; 这样的话会失败,因为这样命名空间将相对于myns 进行搜索,其中不存在任何内容。但我不知道为什么我的代码不起作用。 (我也尝试将index.php 中的命名空间名称更改为autoloading_1,即包含目录的名称,但没有帮助。

【问题讨论】:

    标签: php


    【解决方案1】:

    __autoload 函数必须在全局空间中定义。 否则使用spl_autoload_register。不鼓励使用__autoload()

    【讨论】:

    • 谢谢,有帮助!但是为什么不能使用__autoload() 函数呢?此外,该手册没有提及 spl_autoload_register() 不需要位于全局命名空间中这一事实。
    • 我认为这是理所当然的事情。你可以定义\myns\__autoload\another_namespace\__autoload等。但是其中php唯一可以调用的函数是全局空间中的函数。这就是为什么__autoload 受到限制和劝阻的原因。 spl_autoload_register 为您提供了一种更灵活的方式来注册自动加载,并且不需要在全局命名空间中进行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2013-11-25
    • 2014-04-13
    相关资源
    最近更新 更多