Class naming and namespaces: best practice as an extension author?
The conventional approach

Generally, the safe play is to make a file like &lt;myextension&gt;/CRM/MyExtension/MyClass.php:

&lt;?php
class CRM_MyExtension_MyClass { ...}


(Be sure to match the capitalization of files and classes.)

Most documentation and tooling is based on CRM_* conventions, and a handful of things in core (such as civicrm_payment_processor_type.class_name) make quirky assumptions which only work with CRM_* classes.

How it works: In civix-based extensions, the default hook_civicrm_config adds your extension to the include_path. The classloader CRM_Core_ClassLoader searches the include_path automatically for CRM_* classes.

Critique: In older PHP projects, it was common to automatically link the class-loading with the include_path, but in large codebases this can lead to a large number of file-system checks. Now-a-days many frameworks will reduce lookups by pre-generating some kind of map (namespaces&lt;=>directories or classes&lt;=>files).

The PSR-4 approach (Civi v4.7+)

PSR-4 is a more contemporary technique in which you explicitly map a directory to a namespace. Many PHP developers have been exposed to PSR-4 through composer.json. Civi v4.7 adds CRM_Extension_ClassLoader; with this, you can use info.xml to declare similar mappings:

&lt;extension key="..." type="module"&gt;
  ...
  &lt;classloader&gt;
    &lt;psr4 prefix="My\Namespace\" path="src" /&gt;
  &lt;/classloader&gt;
  ...
&lt;/extension&gt;


In this case, the file &lt;myextension&gt;/src/Foo.php would look like:

&lt;?php
namespace My\Namespace;
class Foo { ... }


In terms of lookup performance and caching, this should be better than CRM_Core_ClassLoader. However, it doesn't have full parity with CRM_* in terms of documentation / tooling / testing.

Custom class loader

You should be able to register your own class-loaders -- e.g. just call spl_autoload_register(...) in your module's main PHP file (perhaps in hook_civicrm_config). If you do this, I suggest following a convention like PSR-0 or PSR-4.

Compared to the PSR-4/Civi v4.7 approach above:


Pro: Should be compatible with any version of Civi
Con: Requires more lines of code
Con: Has the same issue of negligible documentation / tooling / testing


PHPUnit Base Classes

There is an issue if you want to write a custom base-class for PHPUnit tests within an extension -- which is the topic of Does class autoloading not work in standalone phpunit testing?