PHPackages                             bermudaphp/finder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. bermudaphp/finder

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

bermudaphp/finder
=================

v2.0(11mo ago)051MITPHPPHP ^8.4

Since May 9Pushed 11mo ago1 watchersCompare

[ Source](https://github.com/bermudaphp/classFinder)[ Packagist](https://packagist.org/packages/bermudaphp/finder)[ RSS](/packages/bermudaphp-finder/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (4)Versions (4)Used By (1)

Bermuda Class Finder
====================

[](#bermuda-class-finder)

**[Русская версия](README.RU.md)**

[![PHP Version](https://camo.githubusercontent.com/9c2f8ad80d34105266a94c4c06234f8ed18c968d3595039c2d9a7becd1e71c8b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e342d626c75652e737667)](https://php.net/)[![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

A powerful and flexible PHP library for discovering and filtering PHP classes and related elements (classes, interfaces, traits, enums) in your codebase. Built with performance in mind and leveraging PHP 8.4+ features.

Features
--------

[](#features)

- 🔍 **Smart Discovery**: Find classes, interfaces, traits, and enums in specified directories
- 🎯 **Advanced Filtering**: Rich set of filters with optimized performance
- 🚀 **High Performance**: Optimized algorithms with early termination and efficient pattern matching
- 🔄 **Event System**: Listener-based notifications for discovered elements
- 🎨 **Attribute Support**: Deep search through PHP 8+ attributes with pattern matching
- 📦 **PSR-11 Compatible**: Full dependency injection container support
- 🧩 **Extensible**: Easy to extend with custom filters and listeners

Installation
------------

[](#installation)

```
composer require bermudaphp/finder
```

Requirements
------------

[](#requirements)

- PHP 8.4 or higher

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

```
use Bermuda\ClassFinder\ClassFinder;

// Create finder instance
$finder = new ClassFinder();

// Find all PHP classes in directories
$classes = $finder->find(['src/', 'app/']);

foreach ($classes as $filename => $classInfo) {
    echo "Found: $classInfo->fullQualifiedName in $filename\n";
}
```

### With Filters

[](#with-filters)

```
use Bermuda\ClassFinder\ClassFinder;
use Bermuda\ClassFinder\Filter\{
    InstantiableFilter,
    ImplementsFilter,
    AttributeSearchFilter
};

// Find instantiable classes that implement specific interfaces
$finder = new ClassFinder([
    new InstantiableFilter(),
    new ImplementsFilter(['Serializable', 'Countable']),
    new AttributeSearchFilter(['Route'])
]);

$results = $finder->find('src/');
```

Available Filters
-----------------

[](#available-filters)

### Class Type Filters

[](#class-type-filters)

#### InstantiableFilter

[](#instantiablefilter)

Finds classes that can be instantiated (not abstract, interfaces, or traits):

```
use Bermuda\ClassFinder\Filter\InstantiableFilter;

$filter = new InstantiableFilter();
// Matches: class UserService { ... }
// Excludes: abstract class BaseService { ... }
```

#### IsAbstractFilter

[](#isabstractfilter)

Finds abstract classes:

```
use Bermuda\ClassFinder\Filter\IsAbstractFilter;

$filter = new IsAbstractFilter();
// Matches: abstract class BaseController { ... }
```

#### IsFinalFilter

[](#isfinalfilter)

Finds final classes:

```
use Bermuda\ClassFinder\Filter\IsFinalFilter;

$filter = new IsFinalFilter();
// Matches: final class UserService { ... }
```

### Interface and Inheritance Filters

[](#interface-and-inheritance-filters)

#### ImplementsFilter

[](#implementsfilter)

Finds classes implementing specific interfaces:

```
use Bermuda\ClassFinder\Filter\ImplementsFilter;

// Single interface
$filter = new ImplementsFilter('Serializable');

// Multiple interfaces (ALL required - AND logic)
$filter = new ImplementsFilter(['Serializable', 'Countable']);

// Any interface (OR logic)
$filter = ImplementsFilter::implementsAny(['Serializable', 'Countable']);
```

#### SubclassFilter

[](#subclassfilter)

Finds classes extending a specific parent class:

```
use Bermuda\ClassFinder\Filter\SubclassFilter;

$filter = new SubclassFilter('App\\Controller\\AbstractController');
// Finds all classes extending AbstractController
```

### Callable Filter

[](#callable-filter)

#### CallableFilter

[](#callablefilter)

Finds callable classes (classes with `__invoke` method):

```
use Bermuda\ClassFinder\Filter\CallableFilter;

$filter = new CallableFilter();
// Matches: class MyClass { public function __invoke() { ... } }
```

### Pattern Matching Filters

[](#pattern-matching-filters)

#### PatternFilter

[](#patternfilter)

Smart pattern matching with automatic target detection:

```
use Bermuda\ClassFinder\Filter\PatternFilter;

// Search in class names
$filter = new PatternFilter('*Controller');     // Classes ending with "Controller"
$filter = new PatternFilter('Abstract*');       // Classes starting with "Abstract"
$filter = new PatternFilter('*Test*');          // Classes containing "Test"

// Search in namespaces
$filter = new PatternFilter('App\\Controllers\\*');  // Classes in Controllers namespace

// Search in full qualified names
$filter = new PatternFilter('*\\Api\\*Controller');  // API controllers

// Static helpers for common patterns
$filter = PatternFilter::exactMatch('UserController');
$filter = PatternFilter::contains('Service');
$filter = PatternFilter::startsWith('Abstract');
$filter = PatternFilter::endsWith('Controller');
$filter = PatternFilter::namespace('App\\Services');
```

### Attribute Filters

[](#attribute-filters)

#### Deep Search Feature

[](#deep-search-feature)

The `deepSearch` parameter in attribute filters controls the scope of attribute searching:

- **`deepSearch: false` (default)**: Searches only for attributes on the class itself
- **`deepSearch: true`**: Extends search to include attributes on class members:
    - Method attributes
    - Property attributes
    - Constant attributes

```
// Example class with attributes at different levels
class UserController
{
    #[Inject]
    private UserService $userService;

    #[Route('/users')]
    #[Auth('admin')]
    public function index(): Response
    {
        // method implementation
    }

    #[Deprecated]
    public const STATUS_ACTIVE = 1;
}
```

#### AttributeSearchFilter

[](#attributesearchfilter)

Advanced attribute filtering with multiple search options:

```
use Bermuda\ClassFinder\Filter\AttributeSearchFilter;

// Basic search - only class-level attributes
$filter = new AttributeSearchFilter(['Route', 'Controller']);

// Deep search - includes method, property, and constant attributes
$filter = new AttributeSearchFilter(['Inject'], deepSearch: true);
// Will find UserController because $userService has #[Inject]

// Mixed exact names and patterns with deep search
$filter = new AttributeSearchFilter(['Route', '*Test*', 'Api*'], deepSearch: true);

// AND logic with deep search - must have ALL attributes (anywhere in class)
$filter = new AttributeSearchFilter(['Route', 'Auth'], matchAll: true, deepSearch: true);
// Will find UserController because it has both #[Route] and #[Auth] on methods

// Comparison of search scopes:
// Without deep search - only finds classes with Route attribute on class declaration
$classOnlyFilter = new AttributeSearchFilter(['Route'], deepSearch: false);

// With deep search - finds classes with Route on class OR on any method/property/constant
$deepFilter = new AttributeSearchFilter(['Route'], deepSearch: true);

// Static helpers with deep search
$filter = AttributeSearchFilter::hasAttribute('Inject', deepSearch: true);
$filter = AttributeSearchFilter::hasAnyAttribute(['Route', 'Controller'], deepSearch: true);
$filter = AttributeSearchFilter::hasAllAttributes(['Route', 'Middleware'], deepSearch: true);
```

#### AttributePatternFilter

[](#attributepatternfilter)

Pattern matching for attribute names:

```
use Bermuda\ClassFinder\Filter\AttributePatternFilter;

// Basic pattern matching - only class-level attributes
$filter = new AttributePatternFilter('*Route*');
$filter = new AttributePatternFilter('Api*');

// Deep search - includes attributes on methods, properties, constants
$filter = new AttributePatternFilter('*Route*', deepSearch: true);
// Will find UserController because index() method has #[Route('/users')]

$filter = new AttributePatternFilter('*Inject*', deepSearch: true);
// Will find UserController because $userService property has #[Inject]

// Comparison of search scopes:
// Without deep search - only finds classes with Http* attributes on class
$classOnlyFilter = new AttributePatternFilter('Http*', deepSearch: false);

// With deep search - finds classes with Http* on class OR members
$deepFilter = new AttributePatternFilter('Http*', deepSearch: true);

// Optimized static helpers with deep search
$filter = AttributePatternFilter::exactAttribute('HttpGet', deepSearch: true);
$filter = AttributePatternFilter::anyAttribute(['Route', 'HttpGet'], deepSearch: true);
$filter = AttributePatternFilter::attributePrefix('Http', deepSearch: true);
```

Filter Combination
------------------

[](#filter-combination)

### ChainableFilter (AND Logic)

[](#chainablefilter-and-logic)

Combines multiple filters with AND logic - an element must pass ALL filters to be accepted:

```
use Bermuda\Filter\ChainableFilter;
use Bermuda\ClassFinder\Filter\{
    InstantiableFilter,
    PatternFilter,
    AttributeSearchFilter
};

// All conditions must be true
$chainFilter = new ChainableFilter([
    new InstantiableFilter(),                // AND: must be instantiable
    new PatternFilter('*Controller'),        // AND: must end with "Controller"
    new AttributeSearchFilter(['Route'])     // AND: must have Route attribute
]);

$finder = new ClassFinder([$chainFilter]);
$strictControllers = $finder->find('src/Controllers/');
```

### OneOfFilter (OR Logic)

[](#oneoffilter-or-logic)

Combines multiple filters with OR logic - an element only needs to pass ONE filter to be accepted:

```
use Bermuda\Filter\OneOfFilter;
use Bermuda\ClassFinder\Filter\{
    PatternFilter,
    AttributeSearchFilter,
    ImplementsFilter
};

// Any condition can be true
$orFilter = new OneOfFilter([
    new PatternFilter('*Controller'),            // OR: ends with "Controller"
    new PatternFilter('*Service'),               // OR: ends with "Service"
    new AttributeSearchFilter(['Component']),    // OR: has Component attribute
    new ImplementsFilter('App\\Contracts\\HandlerInterface') // OR: implements HandlerInterface
]);

$finder = new ClassFinder([$orFilter]);
$flexibleResults = $finder->find('src/');
```

### Complex Filter Combinations

[](#complex-filter-combinations)

Combine different logic types for sophisticated filtering:

```
use Bermuda\Filter\{ChainableFilter, OneOfFilter};
use Bermuda\ClassFinder\Filter\{
    InstantiableFilter,
    PatternFilter,
    AttributeSearchFilter,
    ImplementsFilter
};

// Complex logic: Must be instantiable AND (Controller OR Service OR has Route attribute)
$complexFilter = new ChainableFilter([
    new InstantiableFilter(),  // Must be instantiable
    new OneOfFilter([          // AND any of these:
        new PatternFilter('*Controller'),        // - ends with "Controller"
        new PatternFilter('*Service'),           // - ends with "Service"
        new AttributeSearchFilter(['Route'])     // - has Route attribute
    ])
]);

$finder = new ClassFinder([$complexFilter]);
$results = $finder->find('src/');
```

Advanced Usage
--------------

[](#advanced-usage)

### Combining Multiple Filters

[](#combining-multiple-filters)

```
use Bermuda\ClassFinder\ClassFinder;
use Bermuda\ClassFinder\Filter\{
    InstantiableFilter,
    PatternFilter,
    AttributeSearchFilter
};

$finder = new ClassFinder([
    new InstantiableFilter(),                    // Only instantiable classes
    new PatternFilter('*Controller'),            // Class names ending with "Controller"
    new AttributeSearchFilter(['Route'])         // Must have Route attribute
]);

$controllers = $finder->find('src/Controllers/');
```

### Using with Dependency Injection

[](#using-with-dependency-injection)

```
use Bermuda\ClassFinder\ClassFinder;
use Psr\Container\ContainerInterface;

// Create from container
$finder = ClassFinder::createFromContainer($container);
```

### Event Listeners

[](#event-listeners)

Listen for discovered classes:

```
use Bermuda\ClassFinder\{ClassFinder, ClassNotifier};
use Bermuda\ClassFinder\ClassFoundListenerInterface;
use Bermuda\Tokenizer\ClassInfo;

class MyListener implements ClassFoundListenerInterface
{
    public function handle(ClassInfo $info): void
    {
        echo "Found class: {$info->fullQualifiedName}\n";
    }
}

// Create notifier with listener
$notifier = new ClassNotifier([new MyListener()]);

// Find and notify
$finder = new ClassFinder();
$classes = $finder->find('src/');
$notifier->notify($classes);
```

### Search Modes

[](#search-modes)

Control what types of class elements to discover using bitwise flags:

```
use Bermuda\ClassFinder\ClassFinder;
use Bermuda\Tokenizer\TokenizerInterface;

$finder = new ClassFinder();

// Search only for classes
$results = $finder->find('src/', [], TokenizerInterface::SEARCH_CLASSES);

// Search only for interfaces
$results = $finder->find('src/', [], TokenizerInterface::SEARCH_INTERFACES);

// Search only for traits
$results = $finder->find('src/', [], TokenizerInterface::SEARCH_TRAITS);

// Search only for enums
$results = $finder->find('src/', [], TokenizerInterface::SEARCH_ENUMS);

// Combine search modes with bitwise OR
$results = $finder->find('src/', [],
    TokenizerInterface::SEARCH_CLASSES | TokenizerInterface::SEARCH_INTERFACES
);

// Search for everything (default) - classes, interfaces, traits, enums
$results = $finder->find('src/', [], TokenizerInterface::SEARCH_ALL);
```

#### Available Search Mode Constants:

[](#available-search-mode-constants)

- `SEARCH_CLASSES = 1` - Find only classes
- `SEARCH_INTERFACES = 2` - Find only interfaces
- `SEARCH_TRAITS = 4` - Find only traits
- `SEARCH_ENUMS = 8` - Find only enums
- `SEARCH_ALL = 15` - Find all OOP elements (default)

### Working with Results

[](#working-with-results)

```
use Bermuda\ClassFinder\ClassFinder;

$finder = new ClassFinder();
$classes = $finder->find('src/');

// Count results
echo "Found " . count($classes) . " classes\n";

// Convert to array
$array = $classes->toArray();

// Add filters dynamically
$filtered = $classes->withFilter(new InstantiableFilter());

// Remove filters
$unfiltered = $classes->withoutFilter($someFilter);
```

Performance Tips
----------------

[](#performance-tips)

1. **Use specific filters**: The more specific your filters, the faster the search
2. **Order matters**: Place the most restrictive filters first
3. **Pattern optimization**: Simple patterns (prefix\*, \*suffix, *contains*) are automatically optimized
4. **Reflection caching**: Repeated searches on the same classes benefit from reflection caching

Configuration
-------------

[](#configuration)

### Container Configuration

[](#container-configuration)

```
// config/dependencies.php
use Bermuda\ClassFinder\{
    ClassFinder,
    ClassFoundListenerProviderInterface,
    ClassFoundListenerProvider,
    ConfigProvider
};

return [
    'config' => [
        ConfigProvider::CONFIG_KEY_FILTERS => [
            // Your default filters
        ],
        ConfigProvider::CONFIG_KEY_LISTENERS => [
            // Your listeners
        ]
    ],

    ClassFoundListenerProviderInterface::class =>
        fn() => ClassFoundListenerProvider::createFromContainer($container)
];
```

Examples
--------

[](#examples)

### Find All Controllers

[](#find-all-controllers)

```
$finder = new ClassFinder([
    new InstantiableFilter(),
    new PatternFilter('*Controller'),
    new SubclassFilter('App\\Controller\\BaseController')
]);

$controllers = $finder->find('src/Controllers/');
```

### Find Services with Dependency Injection

[](#find-services-with-dependency-injection)

```
$finder = new ClassFinder([
    new InstantiableFilter(),
    new AttributeSearchFilter(['Service'], deepSearch: true),
    new PatternFilter('*Service')
]);

$services = $finder->find('src/Services/');
```

### Find Classes with Deep Attribute Search

[](#find-classes-with-deep-attribute-search)

```
// Find all classes that use dependency injection anywhere in the class
$finder = new ClassFinder([
    new AttributeSearchFilter(['Inject', 'Autowired'], deepSearch: true)
]);

$diClasses = $finder->find('src/');

// Find API-related classes by checking for routing attributes in methods
$finder = new ClassFinder([
    new InstantiableFilter(),
    new AttributePatternFilter('*Route*', deepSearch: true) // Checks class AND method attributes
]);

$apiClasses = $finder->find('src/');
```

### Find Test Classes

[](#find-test-classes)

```
$finder = new ClassFinder([
    new PatternFilter('*Test'),
    new SubclassFilter('PHPUnit\\Framework\\TestCase')
]);

$tests = $finder->find('tests/');
```

### Find API Endpoints

[](#find-api-endpoints)

```
$finder = new ClassFinder([
    new InstantiableFilter(),
    new AttributeSearchFilter(['Route', 'ApiResource'], deepSearch: true)
]);

$endpoints = $finder->find('src/Api/');
```

### Complex Filter Logic

[](#complex-filter-logic)

```
use Bermuda\Filter\{ChainableFilter, OneOfFilter};

// Find classes that are either Controllers OR Services, but must be instantiable
$finder = new ClassFinder([
    new InstantiableFilter(),  // Must be instantiable
    new OneOfFilter([          // AND (Controller OR Service)
        new PatternFilter('*Controller'),
        new PatternFilter('*Service')
    ])
]);

$handleableClasses = $finder->find('src/');
```

### Flexible Component Discovery

[](#flexible-component-discovery)

```
use Bermuda\Filter\OneOfFilter;

// Find any component-like classes using multiple criteria
$componentFilter = new OneOfFilter([
    new AttributeSearchFilter(['Component', 'Service', 'Repository']),
    new ImplementsFilter(['App\\Contracts\\ComponentInterface']),
    new PatternFilter('App\\Components\\*')
]);

$finder = new ClassFinder([$componentFilter]);
$components = $finder->find('src/');
```

License
-------

[](#license)

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance51

Moderate activity, may be stable

Popularity4

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Total

3

Last Release

341d ago

Major Versions

v1.x-dev → v2.02025-06-12

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/20490712?v=4)[Andrey Shelamkoff](/maintainers/Shelamkoff)[@Shelamkoff](https://github.com/Shelamkoff)

---

Top Contributors

[![Shelamkoff](https://avatars.githubusercontent.com/u/20490712?v=4)](https://github.com/Shelamkoff "Shelamkoff (116 commits)")

---

Tags

class-finderfinderphpphp84

### Embed Badge

![Health badge](/badges/bermudaphp-finder/health.svg)

```
[![Health](https://phpackages.com/badges/bermudaphp-finder/health.svg)](https://phpackages.com/packages/bermudaphp-finder)
```

###  Alternatives

[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[illuminate/session

The Illuminate Session package.

9937.4M753](/packages/illuminate-session)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

96374.6k23](/packages/friendsoftypo3-content-blocks)[symfony/object-mapper

Provides a way to map an object to another object

34885.7k18](/packages/symfony-object-mapper)[hyperf/di

A DI for Hyperf.

182.8M594](/packages/hyperf-di)[shyim/danger-php

Port of danger to PHP

8544.9k](/packages/shyim-danger-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
