当我尝试测试这个类时,使用PSR-4自动加载Composer:
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;
}
}
使用PHPUnit:
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
这是文件/文件夹结构:
src
`-- User
|-- Contracts
| |-- User.php
| `-- UserId.php
|-- User.php
`-- UserId.php
tests
`-- User
|-- UserIdTest.php
`-- UserTest.php
我已就这些问题进行了大量搜索,但我没有找到任何解决方法。
我该如何解决这个问题?
答案 0 :(得分:5)
您无法将类导入已使用相同别名在其中声明的命名空间。
您有\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编译是按文件完成的,并且合理的期望是仅考虑文件的内容。但是,似乎错误是导入“冲突”类时,先前加载的文件中的现有类定义会受到影响。
它以正确的方式修复了PHP 7.0.13:每个单独的文件只能解释自己,如果你想导入一个类并用它的简写名称来使用它,你可以这样做而不管其他任何类可能存在于命名空间中。您只是松开了对这些类的访问 - 这是无关紧要的,因为您的代码首先不使用它们。如果您想要更改,则必须更改导入。
由于opcache通常在命令行上被禁用,因此在使用PHPUnit时可能会触发此错误。
答案 1 :(得分:2)
尝试以下方法:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolderCheese> {
private LayoutInflater layoutInflater;
private static ClickListener clickListener;
private ArrayList<Person> arrayList = new ArrayList<>();
public void setArrayList(ArrayList<Person> arrayList) {
this.arrayList = arrayList;
notifyDataSetChanged();
}
public RecyclerViewAdapter(Context context) {
this.layoutInflater = LayoutInflater.from(context);
}
@Override
public ViewHolderCheese onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = layoutInflater.inflate(R.layout.item_list, viewGroup, false);
return new ViewHolderCheese(view);
}
@Override
public void onBindViewHolder(ViewHolderCheese viewHolderCheese, int i) {
final Person s = arrayList.get(i);
if (s.getName() != null) {
viewHolderCheese.textView_t.setText(s.getName());
viewHolderCheese.phone.setText(s.getPhone());
if (s.getPicture_path() != null) {
Glide.with(viewHolderCheese.picture.getContext())
.load(s.getPicture_path())
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolderCheese.picture);
} else {
final ColorGenerator generator = ColorGenerator.MATERIAL;
final int color = generator.getRandomColor();
final String letter = s.getName().substring(0, 1);
TextDrawable drawable = TextDrawable.builder()
.buildRect(letter, color);
viewHolderCheese.picture.setImageDrawable(drawable);
}
}
}
public void setClickListener(ClickListener clickListener) {
RecyclerViewAdapter.clickListener = clickListener;
}
@Override
public int getItemCount() {
return arrayList.size();
}
public static class ViewHolderCheese extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textView_t;
TextView phone;
ImageView picture;
public ViewHolderCheese(View itemView) {
super(itemView);
textView_t = (TextView) itemView.findViewById(R.id.textview);
phone = (TextView) itemView.findViewById(R.id.phone);
picture = (ImageView) itemView.findViewById(R.id.image);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (clickListener != null) {
clickListener.itemClick(view, getAdapterPosition());
}
}
}
public interface ClickListener {
void itemClick(View v, int position);
}
}
可能是因为你正在进行命名冲突
use User\Contracts\UserId as UserIdContract;
但 User 类的同一名称空间中也有 UserId 。
因此...
use User\Contracts\UserId;
希望它有所帮助!