不理解PHP命名空间,我如何调用另一个类中的函数?

4
我正在尝试使用Azure存储来进行php开发,设置步骤是包含命名空间、包含composer自动加载程序,然后使用Azure类。因此我有以下代码。但是在下面的代码中,当我使用Microgrid类时,由于命名空间不同,它无法找到该类。如何使用其他不属于该命名空间的类?另外,指定命名空间路径的正确方法是什么?它与此页面所在的目录不同,我使用的目录也不在根目录下,我应该从根目录开始吗?
namespace MicrosoftAzure\Storage;
use \MicrosoftAzure\Storage\Common\ServicesBuilder;
use \MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
use \MicrosoftAzure\Storage\Blob\Models\PublicAccessType;
use \MicrosoftAzure\Storage\Common\ServiceException;

require_once '/var/www/html/vendor/autoload.php';


$action = MicroGrid::GetParameter('action');

2
使用 \namespace\where\microgrid\located\MicroGrid; - Wizard
如果你的类没有命名空间,你可以尝试使用这个:$action = \MicroGrid::GetParameter('action'); - Wizard
声明命名空间时,它是来自根目录还是相对路径? - nick
3个回答

4

如果类名不以 \ 开头,则被视为相对于当前命名空间。

这意味着在 MicrosoftAzure\Storage 命名空间内,您可以使用相对命名空间来引用类。

如果您想调用不同命名空间中的一个类,您应该使用完全限定名称来引用它,例如:

$action = \MicrosoftAzure\WhereEver\MicroGrid::GetParameter('action');

或者使用命名空间或唯一类名和完全限定名称。
use \MicrosoftAzure\WhereEver;

或者
use \MicrosoftAzure\WhereEver\MicroGrid;

那么:

$action = MicroGrid::GetParameter('action');

编辑以使其更清晰

命名空间允许我们避免命名冲突,并为避免命名冲突而导致的长名称创建别名。

它取决于您的自动加载程序。举个简单的例子,我创建了一个新项目,并在位于根目录下的index.php中创建了这个自动加载程序。

function __autoload($className){
    //if it's a full name with windows style slashes correct the path
    $file_name = str_replace('\\', '/', $className);
    require_once("vender/src/".$file_name.".php");
}

当我调用$date = new \App\Utility\Date();时,自动加载器将需要此文件:

verdor/src/App/Utility/Date.php

Date.php 中,我使用了这个命名空间:App\Utility;

好的,我不明白命名空间应该如何首先声明,我的Azure库在../vendor/MSAzure/Storage中,而Microgrid在../include/classes中,我应该从根目录声明命名空间吗?我该如何返回以便我可以使用我的Microgrid类? - nick

2

PHP本身没有提供类自动加载器。

PHP有很多自动加载器,而最常见的自动加载器标准是PSR-4,许多框架和应用程序都在使用。

如果您不使用自动加载器,则应在使用之前要求加载每个类文件(以及递归依赖项)。

Azure使用Composer Autoloader和PSR-4。

在您的项目中应使用Composer Autoloader,然后从正确的命名空间导入您的类(您的示例代码中未导入它)。


我正在使用Composer,忘记包含那行代码了,你说的导入是什么意思? - nick
use Some\Class\Namespace\ClassName 是一个导入语句。 你没有在任何地方导入 MicroGrid 类。 - Elias Soares
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Elias Soares
Microgrid是一个不相关的类,它是使用自动加载器包含的。它也在不同的目录中,我想这是我的问题的一部分.. Azure库位于../vendor/MSAzure/Storage,而microgrid位于../include/classes,我应该从根目录声明命名空间吗?所以它会像../html/vendor/MSAzure这样,我可以使用../html/include/microgrid吗? - nick
然后,您应该在文件顶部使用PHP的require('path/to/your/class.php);手动加载您的MicroGrid类。 - Elias Soares

1

命名空间基本上将你的类组合在一起。你可以通过显式使用它来使用命名空间之外的内容,例如:

namespace App;

use Illuminate\Database\Eloquent\Model;

在这种情况下,我将这个类和其他类分组到一个名为“App”的命名空间中,但是我想在这个类中使用Eloquent提供的“Model”(Eloquent类具有“Illuminate\Database\Eloquent”的命名空间)。
如果'Microgrid'不是您当前命名空间的一部分,则需要在您的'use'语句中显式添加其命名空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接