Ffile2fix
Sign in Get started

How to fix "Cannot declare class, because the name is already in use"

Fatal error: Cannot declare class PHPMailer, because the name is already in use in /home/user/public_html/wp-content/plugins/smtp-plugin/lib/class-phpmailer.php on line 30

PHP loaded a class definition when a class (or interface, trait or enum) with the same fully qualified name already exists. Usually the same file is included twice, or two plugins bundle their own copy of the same library.

Also appears as: PHP Fatal error: Cannot declare class App\Models\User, because the name is already in use · Fatal error: Cannot declare interface LoggerInterface, because the name is already in use · Fatal error: Cannot redeclare class Foo (PHP 5/7.x)

Common causes

  • Two plugins or a plugin and theme bundle the same library (PHPMailer, Guzzle, Carbon) without namespacing it
  • A class file is loaded with require instead of require_once, or both manually and by Composer
  • A duplicate copy of a file (backup like User.php.bak or User-old.php) in an autoloaded folder
  • A class with the same name as an imported alias in the same file (use App\Foo; class Foo {})
  • A stale Composer classmap pointing two names at the same file

How to fix it

  1. Find the first declaration. Use (new ReflectionClass('PHPMailer'))->getFileName() just before the failing include, or search the codebase for 'class PHPMailer' to find both copies.
  2. Use require_once or the autoloader. Replace require/include of class files with require_once, or remove the manual include when Composer already autoloads the class.
  3. Guard optional bundled libraries. When shipping a plugin, wrap includes in if (!class_exists('PHPMailer\PHPMailer\PHPMailer', false)) or, better, prefix vendor namespaces with a tool like PHP-Scoper.
  4. Identify conflicting plugins. In WordPress, the plugin path in the error is the second loader. Deactivate plugins one by one (or rename folders via FTP) to find which pair conflicts, then update or replace one.
  5. Remove duplicate files. Delete backup copies of class files from autoloaded directories and run composer dump-autoload.
  6. Fix alias clashes. If a use statement imports a name that the file then declares, rename the import with use Vendor\Foo as VendorFoo.

PHP

if (!class_exists(\PHPMailer\PHPMailer\PHPMailer::class, false)) {
    require_once __DIR__ . '/lib/PHPMailer.php';
}

// find where the existing class came from
// echo (new ReflectionClass('PHPMailer'))->getFileName();

How to stop it happening again

  • Load classes only through Composer's autoloader
  • Namespace and scope vendor libraries bundled in plugins
  • Keep backup files out of the project tree

Frequently asked questions

How is this different from 'Cannot redeclare function'?

It is the same problem for classes, interfaces, traits and enums instead of functions. The fixes are similar: load once, namespace, or remove the duplicate.

Why does it happen only when two specific plugins are active?

Each plugin bundles the same library under the same global class name. Whichever loads second crashes. Update both; well-maintained plugins scope their dependencies.

Does Composer prevent this?

Composer's autoloader only loads a class once, but it cannot stop code that includes the same class file manually or a second vendor folder from another plugin.