在 PHPUnit 中使用 composer 的自动加载时出现名称已在使用中的致命错误
Name already in use fatal error using composer's autoload in PHPUnit
使用 PSR-4 自动加载和 Composer,当我尝试测试这个 class:
namespace User;
use User\Contracts\UserId;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserId $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
使用PHP单位:
use User\Contracts\UserId;
class UserTest extends \PHPUnit_Framework_TestCase
{
public function test_the_identifier_can_be_used_as_string()
{
$identifier = m::mock(UserId::class);
$identifier->shouldReceive('__toString')->once()->andReturn('foo');
$user = new User($identifier);
$this->assertSame('foo', (string) $user->getId());
}
}
我在控制台收到这个错误
PHP Fatal error: Cannot use User\Contracts\UserId as UserId because the name is already in use in /src/User/User.php on line 5
这是 file/folder 结构:
src
`-- User
|-- Contracts
| |-- User.php
| `-- UserId.php
|-- User.php
`-- UserId.php
tests
`-- User
|-- UserIdTest.php
`-- UserTest.php
我已经对这个问题做了很多搜索,但我还没有找到任何解决方案。
- PHP版本:5.6.13-1+deb.sury.org~trusty+3
- PHP单元版本:5.0.3
- OS:Ubuntu 14.04.3 LTS
我该如何解决这个问题?
尝试以下操作:
use User\Contracts\UserId as UserIdContract;
可能您遇到了命名冲突,因为您正在做
use User\Contracts\UserId;
但您在 User class.
的同一命名空间中也有 UserId
所以...
namespace User;
use User\Contracts\UserId as UserIdContract;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserIdContract $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
希望对您有所帮助!
您不能将 class 导入到已经在其中声明了相同别名的命名空间。
您有 \User\UserId
并且想要将 \User\Contracts\UserId
导入 \User
命名空间。这会使快捷方式 UserId
不明确。
http://php.net/manual/en/language.namespaces.importing.php#117334
导入时可以使用别名,也可以直接使用相对路径:
namespace User;
class User implements Contracts\User
{
private $id;
public function __construct(Contracts\UserId $id) {}
}
2018-03-20更新:
有一个错误报告 https://bugs.php.net/bug.php?id=66773 抱怨 PHP 如果在没有操作码缓存的情况下使用会触发此错误,否则不会。原因是使用 opcache 编译是按文件完成的,并且只考虑文件的内容是合理的期望。但是,错误似乎是导入 "conflicting" classes.
时,先前加载文件中的现有 class 定义受阻
它已在 PHP 7.0.13 中以正确的方式修复:每个文件只占其自身,如果您希望导入 class 并按 [=41] 使用它=] 名称,您可以这样做,而不管命名空间中可能存在的任何其他 classes。您只是失去了对这些 classes 的访问权——这无关紧要,因为您的代码一开始就没有使用它们。如果您想要更改,则必须更改导入。
由于 opcache 通常在命令行上被禁用,因此您在使用 PHPUnit 时很可能会触发此错误。
使用 PSR-4 自动加载和 Composer,当我尝试测试这个 class:
namespace User;
use User\Contracts\UserId;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserId $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
使用PHP单位:
use User\Contracts\UserId;
class UserTest extends \PHPUnit_Framework_TestCase
{
public function test_the_identifier_can_be_used_as_string()
{
$identifier = m::mock(UserId::class);
$identifier->shouldReceive('__toString')->once()->andReturn('foo');
$user = new User($identifier);
$this->assertSame('foo', (string) $user->getId());
}
}
我在控制台收到这个错误
PHP Fatal error: Cannot use User\Contracts\UserId as UserId because the name is already in use in /src/User/User.php on line 5
这是 file/folder 结构:
src
`-- User
|-- Contracts
| |-- User.php
| `-- UserId.php
|-- User.php
`-- UserId.php
tests
`-- User
|-- UserIdTest.php
`-- UserTest.php
我已经对这个问题做了很多搜索,但我还没有找到任何解决方案。
- PHP版本:5.6.13-1+deb.sury.org~trusty+3
- PHP单元版本:5.0.3
- OS:Ubuntu 14.04.3 LTS
我该如何解决这个问题?
尝试以下操作:
use User\Contracts\UserId as UserIdContract;
可能您遇到了命名冲突,因为您正在做
use User\Contracts\UserId;
但您在 User class.
的同一命名空间中也有 UserId所以...
namespace User;
use User\Contracts\UserId as UserIdContract;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserIdContract $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
希望对您有所帮助!
您不能将 class 导入到已经在其中声明了相同别名的命名空间。
您有 \User\UserId
并且想要将 \User\Contracts\UserId
导入 \User
命名空间。这会使快捷方式 UserId
不明确。
http://php.net/manual/en/language.namespaces.importing.php#117334
导入时可以使用别名,也可以直接使用相对路径:
namespace User;
class User implements Contracts\User
{
private $id;
public function __construct(Contracts\UserId $id) {}
}
2018-03-20更新:
有一个错误报告 https://bugs.php.net/bug.php?id=66773 抱怨 PHP 如果在没有操作码缓存的情况下使用会触发此错误,否则不会。原因是使用 opcache 编译是按文件完成的,并且只考虑文件的内容是合理的期望。但是,错误似乎是导入 "conflicting" classes.
时,先前加载文件中的现有 class 定义受阻它已在 PHP 7.0.13 中以正确的方式修复:每个文件只占其自身,如果您希望导入 class 并按 [=41] 使用它=] 名称,您可以这样做,而不管命名空间中可能存在的任何其他 classes。您只是失去了对这些 classes 的访问权——这无关紧要,因为您的代码一开始就没有使用它们。如果您想要更改,则必须更改导入。
由于 opcache 通常在命令行上被禁用,因此您在使用 PHPUnit 时很可能会触发此错误。