0

I have a php (Laravel) project with several namespace mappings applied in the composer.json, like this:

{
  "autoload": {
    "psr-4": {
      "App\\": [
        "app/"
      ],
      "Modules\\": [
        "app/Domains/Example/"
      ]
    }
  }
}

And a class in app/Domains/Example/ExampleClass.php:

namespace Modules;

class ExampleClass {}

When PhpStorm auto-imports a class, it always seems to prefer the App\ mapping, while I would prefer it to use Modules.

Is there any way of specifying which namespace PhpStorm should use?

5
  • 1
    This isn't even a valid class path: app/Domains/Example/ExampleClass. PhpStorm will use the correct class path / namespace. Something else seems to be wrong here, but since you do not provide the class declaration and class path you provide is wrong, it's difficult to guess what. Commented Jan 21 at 8:37
  • Ah yes sorry what I meant to type was use app/Domains/Example; new ExampleClass(); or something like that. The class declaration is irrelevant, and I think the class path is is also irrelevant, but the folders are named the same as in the namespace. Commented Jan 22 at 9:05
  • Neither is irrelevant; or I wouldn't have asked about it. The class definition and namespace statement for the class, and exact code you use and expect, are important. Please edit your question accordingly. use app/Domains/Exampleis also incorrect. Please use actual working code. You seem to be confusing file paths with class paths. Commented Jan 22 at 9:09
  • I think there's some misunderstanding here. There is no "mapped namespace of the class"; the namespace of a class is always declared with a namespace directive at the top of the file (or, technically a namespace {} block). You could put all your files in a single folder, named 1.php, 2.php, etc, and require them with PHP just fine. The only thing that config in Composer does is tell the "autoloader" where to find your files; it doesn't change those classes in any way. Commented Jan 22 at 9:19
  • So, based on your latest edit, are you saying that you have two classes, called e.g. App\Foo and Modules\Foo, and when you type Foo, PhpStorm is guessing that you mean App\Foo but you want it to guess Modules\Foo? Commented Jan 22 at 10:06

1 Answer 1

1

The order in PhpStorm is alphabetically and includes the namespaces.

Small example, let's say we have a class Foo in two namespaces:

$ make classes-and-namespaces 
grep -r --include='*.php' --exclude-dir=.git --exclude-dir=vendor \
    -e 'class\|namespace' -n .
./app/Foo.php:3:namespace App;
./app/Foo.php:5:class Foo
./app/Domains/Example/Foo.php:3:namespace Modules;
./app/Domains/Example/Foo.php:5:class Foo
./test.php:3:namespace test;
  1. App\Foo
  2. Modules\Foo

When we test PhpStorms auto-completion at this point:

<?php

namespace test;

$a = new Foo

It finds those two and shows their namespaces:

+-------------------+
| (c) Foo [App]     |
| (c) Foo [Modules] |
+-------------------+

You can then select which ones you want and it will be imported above the statement:

<?php

namespace test;

use Modules\Foo;

$a = new Foo();

(here, I was selecting the second entry and also added the semicolon ";")

Therefore the expectation that it always takes App\Foo is wrong, it is only suggested as the first hit, and only unless you make that selection, it will be App\Foo.

So much about the general example and to ensure we're on the same page.


Is there any way of specifying which namespace PhpStorm should use?

Now if that poses you a problem or that is the itch to scratch, you have a couple of options.

The one I'd perhaps favorite myself is to make use of the uppercase letters. It goes over namespaces and classnames.

Let's say I want the fully qualified class name (FQCN) Modules\Foo from the example above, I can type MF instead:

<?php

namespace test;

$a = new MF

PhpStorm will then prefer it as first entry:

+--------------------------+
| (c) Foo [Modules]        |
| (c) _M_essage_F_ormatter |
| ...                      |
+--------------------------+

The other suggestions are highlighted on the matching letters. This is normally quick to type, especially if you need something from longer class-name (RII -> _R_ecursive_I_terator_I_terator).

By the basic principle to choose the class to use, it then will be selected from the menu (see above).

Take note, that the moment you already have a class in use with the same classname, all other FQCNs with the same classname will be used under their FQCNs.

That is, if you are in the namespace named Example, Foo will be preferred.

Nevertheless, FQCNs can then be aliased by a quick-fix (Alt+Enter).


Now if you run into the problem really often, this may show that some class-names are cumbersome and may signal they probably have not the name you want them to have.

If so, I'd suggest then to rename that class: Have the cursor over the class-name and:

Keyboard Menu/Action
‍Shift‍‍+‍‍F6‍ Refactor -> Rename

Original answer before the edit:

Is there any way to make PhpStorm use the mapped namespace of a class, instead of the original one, when it automatically inserts use statements?

Yes, the feature is called Auto Import (jetbrains.com). Configure it to your liking.

The feature is known as the Import Assistant, as the linked docs say, but I always look it up with auto-import in the settings.


See as well the Composer and Directories settings, PhpStorm can be configured that include paths are updated from the composer.json configuration file and PSR mappings are also with the Directories.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that at least pointed me in the right direction! Turns the reason PhpStorm behaves this way is because one of the root directories of the mapped class is also mapped to a different namespace, which PhpStorm seems to prefer when autocompleting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.