Fixing Duplicate Class Errors with Locally Symlinked Vendor in PHPStorm

Since we have moved to using local composer packages for addons, composer has created symlinks from the vendor folder to the actual source (such as vendor/kounta/adjustments → addons/adjustments).

This works well from an application standpoint since there is still only one real copy of the files.

However, PHPStorm does not like this at all. There is still an open issue for it.

PHPStorm will index both the original folder and the contents of the symlink and produce a “class defined in multiple locations” error.

This warning can be disabled:

Image for post
Image for post

Unfortunately this is not the end of the story. When command+clicking on a class name it will still present you with a list of two locations for the class, or when looking up files you will still see both (one will be disabled and readonly). There needs to be a better way.

Most of the ways that you would normally go about fixing this do not work, these include:

  1. Marking the individual symlink folders in the vendor folder as Excluded. For some reason PHPStorm ignores this.
  2. More drastically ignoring the whole vendor/kounta folder as Excluded also does not work.

So what’s really happening?

The problem cannot be simply suppressed because PHPStorm gives special attention to folders that are considered a library root.

Since PHPStorm has inbuilt support for composer it will automatically mark all of the appropriate folders inside the vendor as a library root. This works great for code completion (we want this!) but doesn’t work when symlinks are thrown in to the mix.

The only stable solution for this is to explicitly tell PHPStorm that specific folders are not library roots. They must be removed in the Languages & Frameworks > PHP:

Image for post
Image for post

Usually library roots are not in any specific order. If you have many vendor libraries it’s a good idea to sort them with the button at the bottom:

Image for post
Image for post

Once you have removed the library roots for the symlinked folders you should be good to go!

The vendor folder will show the excluded folders in red (just as it looks when the folder is excluded by a different means) but now it’s actually doing what it’s supposed to.

Originally published at on April 6, 2017.

Written by

I’m a data nerd and TDD enthusiast originally from Sydney. Currently working for Uber in New York. My thoughts here are my own. 🤓

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store