Common convention for namespaces in PHP is to start with Vendor\Package , capitalized ( CamelCase StudlyCaps ) with “vendor” and “package” analogous to the composer package name.

There is a bad habit I see often, probably coming from the ZF1 and Pear days, where every word in the class name is a new sub namespace (and a new subdirectory), or child classes are moved into a namespace with the name of the parent class. All this is leading to deeply nested namespaces and class names that have no meaning without their namespace.

Examples from Zend Framework 1 (pseudo namespaces):

Zend_Db_Table_Row_Abstract an abstract base class for Zend_Db_Table_Row , representing a database table row. There are also Zend_Db_Table and Zend_Db .

an abstract base class for , representing a database table row. There are also and . Zend_Pdf_FileParser_Font_OpenType_TrueType a parser for true type font files. The class extends Zend_Pdf_FileParser_Font_OpenType which extends Zend_Pdf_FileParser_Font which extends Zend_Pdf_FileParser

And a current example from Magento 2:

Magento\Catalog\Model\Product\Option\Type\File\Validator – A validator for product options of the type “file”

This makes a very confusing directory structure, deeply nested, and with classes that belong together not necessarily next to each other.

├── Option │ ├── Converter.php │ ├── ReadHandler.php │ ├── Repository.php │ ├── SaveHandler.php │ ├── Type │ │ ├── Date.php │ │ ├── DefaultType.php │ │ ├── Factory.php │ │ ├── File │ │ │ ├── ValidateFactory.php │ │ │ ├── ValidatorFile.php │ │ │ ├── ValidatorInfo.php │ │ │ └── Validator.php │ │ ├── File.php │ │ ├── Select.php │ │ └── Text.php │ ├── Type.php │ ├── UrlBuilder.php │ ├── Validator │ │ ├── DefaultValidator.php │ │ ├── File.php │ │ ├── Pool.php │ │ ├── Select.php │ │ └── Text.php │ └── Value.php ├── Option.php

The other extreme is no sub namespaces at all, leaving all class files in one directory (or even all classes in one file)

This is perfectly fine for a small package with about a dozen classes, but not if it gets bigger.

Since I prefer having many small classes over a few big ones, I have to find a middle ground. Otherwise the code base will look complex at first glance where it actually is not, just because the parts are shuffled without sensible arrangement.

But what is wrong with the examples above?

Unnecessary deep nesting Take the Zend_Db classes: Databases, tables, rows and columns (and more) make up a database schema and are tightly coupled with each other. You won’t have tables without rows and rows without tables. So if all these classes logically belong together, why should I look for them in different directories? If I browse the code in the IDE or on Github I want to be able to navigate quickly between classes that belong together . And if it is unfamiliar code, I want to quickly grasp which classes belong together. This is easier if they are in the same place, for example like this: RelationalDbSchema ├── Database.php ├── Table.php ├── Row.php ├── Column.php With the PDF file parser classes it is similar, although they have another problem: overuse of inheritance. That aside, a better structure could look like this: FileParser ├── BaseFileParser.php ├── FontFileParser.php ├── OpenTypeFontFileParser.php ├── TrueTypeFontFileParser.php

Take the Zend_Db classes: Databases, tables, rows and columns (and more) make up a database schema and are tightly coupled with each other. You won’t have tables without rows and rows without tables. So if all these classes logically belong together, why should I look for them in different directories? If I browse the code in the IDE or on Github I want to be able to . And if it is unfamiliar code, I want to quickly grasp which classes belong together. This is easier if they are in the same place, for example like this: Hard to find classes Most IDEs have a feature to search for classes by name, for example for code completion. Now if you have 50 classes called “File” or “Validation” in different namespaces used for entirely different things, you are making it hard to find the right one. However, if there is one single “FileOptionValidation” class, I can find and use it with just a few keystrokes.

So here are some rules I came up with that work well for me so far:

Keep classes organized

Keep namespace depth as flat as possible . This makes it easier to navigate the code.

. This makes it easier to navigate the code. Start with zero , i.e. Vendor\Package\Class , and only introduce sub namespaces if there is need for it (see below).

, i.e. , and only introduce sub namespaces if there is need for it (see below). If the number of classes in a namespace is too big to find your way in it, think(!) about breaking it apart 10 or even 50 classes or interfaces in a namespace are still okay, if they really belong together

about 10 or even 50 classes or interfaces in a namespace are still okay, if they really Think of each sub namespace as a separate component and keep coupling between the components small . This will help you organize the namespaces in a sensible way.

and keep . This will help you organize the namespaces in a sensible way. The class name should always be descriptive enough to work without the namespace (i.e. ProductRepository instead of Product\Repository ). This will help to quickly find the right classes. Also you can let your IDE import them automatically and you won’t need to define aliases all the time.

enough to work (i.e. instead of ). This will help to quickly find the right classes. Also you can let your IDE import them automatically and you won’t need to define aliases all the time. Avoid namespaces that contain both, classes and sub-namespaces. This is the least important rule, but I think it can be a useful guideline to keep the distance between classes that belong together low. An exception can be a class that serves as single entry point for the whole package that has sub-namespaces. This will reside as only class at the top level next to the sub-namespaces to make it obvious that this is where you start using the package. Reddit user LtAramaki makes an interesting point: I can see you seem to equate “namespace” and “package”, but they really aren’t the same thing I have thought about it and could not find arguments against a class like Vendor\Package as single entry point for the package. I will consider this in the future.

I mostly stick to the “one class per file” convention and PSR-4, i.e. namespaces mapped to directories. The reasons are practical: autoloader compatibility and the “principle of least astonishment”.

“Private classes” inside another class file are a rare exception and only if they are not used anywhere outside that “parent” class.

How do you organize your namespaces?