【问题标题】:Php unusual fatal error with "name is already in use"带有“名称已在使用”的 PHP 异常致命错误
【发布时间】:2012-08-12 21:42:37
【问题描述】:

在我的本地开发机器(php 5.3.14)上,我可以使用这样的类:

<?php

namespace Shop\Repository;

use Shop\Entity\Day;
use Doctrine\ORM\EntityRepository;

class Product extends EntityRepository
{
    // Code
}

该类存储在 /my/src/Shop/Repository/Product.php(符合 PSR-0)中。我有一个Shop\Repository\Day,位于/my/src/Shop/Repository/Day.php。

但是,在我的登台服务器 (php 5.3.10) 上,我收到以下错误:

PHP 致命错误:无法使用 Shop\Entity\Day 作为 Day,因为该名称已在第 5 行的 /my/src/Shop/Repository/Product.php 中使用

我可以理解该消息,如果我将 Shop\Entity\Day 导入别名为 DayEntity,则代码有效。但我无法理解致命错误的原因:为什么这适用于 php 5.3.14(或至少,使用我的配置)而不是 5.3.10(或至少,使用服务器的配置)?

我想问题是因为在命名空间Shop\Repository 中已经加载了一个Day。但这从未导致我的设置出错!怎么回事?

【问题讨论】:

  • use Shop\Entity\Day as EntityDay;,或者只是使用它的完全限定名称来引用它并完全摆脱 use 声明。也许也可以重新阅读this
  • 很明显,如果将一个名为 Day 的类导入到一个已经有一个名为 Day 的类的命名空间中,就会发生冲突。至于为什么它适用于您的本地设置;我在更新日志中看不到任何与 5.4.10 和 5.3.14 之间的命名空间相关的错误修正。是否有可能在您加载 Entity\Day 时本地尚未使用您的 Repository\Day 类?
  • @Leigh 我正在请求完全相同的页面,并使用来自 git 的完全相同的克隆。因此,这一定是一个 (php) 配置问题。
  • @DaveRandom 我猜你是对的。我非常了解命名空间,但是因为这是在我的本地机器上运行的,所以我从来没有想过这可能是一个文件中的问题,其中命名空间声明位于顶部,就像我在此处提供的那样。
  • @JurianSluiman 这都是关于已加载的内容。如果包含 Shop\Repository\Day 类的文件已加载 (included),则名称 Day 已在当前命名空间中使用。如果尚未加载,则该名称未在使用中,您的代码将成功 - 但如果您随后尝试包含 Shop\Repository\Day,那么您将收到相同的错误。通常,如果您有两个来自不同命名空间的同名类,并且您需要在同一个地方引用它们,请使用完全限定名称以避免混淆。你可以像上面那样别名,但我不喜欢它。

标签: php namespaces


【解决方案1】:

以下是我对这种情况的一些解释:

require_once 'ns_class2.php';
// 
namespace ns; // Declaration of the namespace named "ns"
class class2 {} // Declaration of the class "ns/class2"
// In the namespace "ns", "class2" is an alias of  "ns\class2"
// 


require_once 'ns_ns1_ns2_class2.php';
// 
namespace ns\ns1\ns2; // Declaration of the namespace named "ns\ns1\ns2"
class class2 {} // Declaration of the class "ns\ns1\ns2\class2"
// In the namespace "ns\ns1\ns2", "class2" is an alias of "ns\ns1\ns2\class2"
//  

require_once 'ns_ns1_ns2_class1.php';
// 
namespace ns\ns1\ns2; // Declaration of the namespace named "ns\ns1\ns2"
// In the namespace "ns\ns1\ns2", "class2" is an alias of "ns\ns1\ns2\class2"
use ns\class2; // Creation of the alias  "class2" which point to "ns\class2" but class2 is already an alias of ns\ns1\ns2\class2 => ERROR 

所以你应该尝试使用 get_included_files() 在你的服务器和工作站上查看有什么不同,因为加载它们的顺序很重要

这些解释链接自this nice post dmitry 评论

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    • 2023-03-08
    • 2013-10-10
    相关资源
    最近更新 更多