Skip to content

Configuration enhancements for non-standard PHP projects (Drupal, legacy codebases) #44

@syntlyx

Description

@syntlyx

Summary

PHPantom works great for standard Composer projects, but projects like Drupal use a custom class loader that bypasses Composer's autoloading entirely. Three small configuration additions would make PHPantom usable for a large class of real-world PHP projects.


Context: How Drupal loads classes

Drupal does not register module namespaces in composer.json. Instead, it discovers modules at runtime by scanning *.info.yml files and dynamically registering PSR-4 namespaces via its own class loader. This means:

  • vendor/autoload_classmap.php and autoload_psr4.php don't know about any module classes
  • strategy = "self" works around this, but at the cost of surfacing vendor-internal classes

A more targeted solution would be a combination of the three features below.


Requested features

1. includePaths — additional scan directories

Allow specifying extra directories to scan for classes, on top of what Composer knows about. These would be treated like strategy = "self" but scoped to specific paths.

[indexing]
strategy = "composer"
include_paths = ["web/modules", "web/themes", "web/profiles"]

This mirrors intelephense.environment.includePaths and gives precise control without the downsides of global "self" scanning.


2. fileExtensions — treat non-.php files as PHP

Drupal uses several file extensions for valid PHP files:

Extension Purpose
.module Hook implementations, main module file
.install hook_schema(), update hooks
.theme Theme hook implementations
.inc Shared include files

These are plain PHP files with a <?php header. PHPantom currently won't index them.

[indexing]
file_extensions = ["php", "module", "install", "theme", "inc"]

3. LSP initializationOptions — editor-side configuration

Currently the only way to configure PHPantom is via .phpantom.toml committed to the repository. It would be useful to also accept configuration through LSP initializationOptions (passed by the editor in initialize request).

Why this matters:

  • Editor config (Zed settings.json, VS Code settings.json, Neovim) is the natural home for developer-specific settings
  • .phpantom.toml is project-scoped; some settings are developer-scoped
  • Avoids committing editor tooling config into the project repo
  • Consistent with how Intelephense, clangd, and other LSP servers handle this

The schema could mirror .phpantom.toml but as JSON:

{
  "phpantom": {
    "php": { "version": "8.3" },
    "indexing": {
      "strategy": "composer",
      "include_paths": ["web/modules", "web/themes"],
      "file_extensions": ["php", "module", "install", "theme", "inc"]
    }
  }
}

.phpantom.toml and initializationOptions could be merged, with the toml file taking precedence for project-level settings.


Who this affects

  • Drupal projects (one of the largest PHP ecosystems, ~1M+ sites)
  • Legacy codebases using .inc includes
  • Any project with a custom autoloader alongside Composer

Happy to test any of this on a real Drupal codebase and report back.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions