PHPackages                             ju1ius/footprints - 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. [Debugging &amp; Profiling](/categories/debugging)
4. /
5. ju1ius/footprints

ActiveLibrary[Debugging &amp; Profiling](/categories/debugging)

ju1ius/footprints
=================

Filterable backtraces for PHP

0.2(3y ago)0117MITPHPPHP &gt;=8.1

Since Jan 16Pushed 3y ago1 watchersCompare

[ Source](https://github.com/ju1ius/footprints)[ Packagist](https://packagist.org/packages/ju1ius/footprints)[ RSS](/packages/ju1ius-footprints/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (3)Used By (0)

ju1ius/footprints
=================

[](#ju1iusfootprints)

[![codecov](https://camo.githubusercontent.com/e7587255602ce675beca20fe935604703194fafd3ae96b558db2b6a68151dc42/68747470733a2f2f636f6465636f762e696f2f67682f6a75316975732f666f6f747072696e74732f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d304a3651424b52313358)](https://codecov.io/gh/ju1ius/footprints)

Filterable backtraces for PHP

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

[](#installation)

```
composer require ju1ius/footprints
```

Usage
-----

[](#usage)

### Capturing stack traces

[](#capturing-stack-traces)

```
use ju1ius\Footprints\Backtrace;

// Capture the current stack trace
$trace = Backtrace::capture();
// retrieve the array of stack frames
$frames = $trace->frames();

// Capture the current stack trace, skipping the current stack frame
$trace = Backtrace::capture(1);

// Second argument is the flags for \debug_backtrace()
$trace = Backtrace::capture(0, Backtrace::PROVIDE_OBJECT|Backtrace::IGNORE_ARGS);

// You can capture error/exception traces too
try {
    // ...
} catch (\Throwable $err) {
    // Capture the exception trace, skipping the two topmost frames
    $trace = Backtrace::captureThrowable($err, 2);
}
```

### Filtering stack traces

[](#filtering-stack-traces)

To filter backtraces, the `Backtrace::accept()` and `Backtrace::reject()` methods are available, both of which accept a `callable` predicate and returns a filtered `Backtrace` object.

The `$predicate` argument has the following signature: `callable(Frame, int, Frame[]): bool`: it takes a Frame, it's index and the whole frames array and returns a boolean indicating whether the predicate matched.

`Backtrace::accept()` will accept (keep) the frames for which `$predicate` returns a truthy value, while `Backtrace::reject()` will reject (filter-out) the frames for which `$predicate` returns a truthy value.

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Frame;

// Keep only frames for:
// * the top-level foo() function
// * any method named foo() regardless of it's class.
$trace = Backtrace::capture()
    ->accept(fn(Frame $frame) => $frame->function === 'foo');

// Filters out frames for:
// * the top-level foo() function
// * any method named foo() regardless of it's class.
$trace = Backtrace::capture()
    ->reject(fn(Frame $frame) => $frame->function === 'foo');
```

For convenience, this library comes with a few built-in predicates.

### Builtin predicates

[](#builtin-predicates)

#### isFunction(string ...$functionNames)

[](#isfunctionstring-functionnames)

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Predicate;

$trace = Backtrace::capture()->reject(Predicate::isFunction(
    'foo',
    'Acme\\foobar',
));
```

#### isClass(string ...$classNames)

[](#isclassstring-classnames)

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Predicate;

$trace = Backtrace::capture()->reject(Predicate::isClass(
    'Foo',
    'Acme\\FooBar',
));
```

#### isMethod(string ...$methodNames)

[](#ismethodstring-methodnames)

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Predicate;

$trace = Backtrace::capture()->reject(Predicate::isMethod(
    // rejects method `bar` of class `Foo`
    'Foo->bar',
    // rejects static method `baz` of class `Acme\FooBar`
    'Acme\\FooBar::baz',
));
```

#### isNamespace(string ...$namespaces)

[](#isnamespacestring-namespaces)

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Predicate;

$trace = Backtrace::capture()->reject(Predicate::isNamespace(
    // rejects everything in namespace `Acme\Foo` and all it's sub-namespaces.
    'Acme\\Foo',
));
```

#### isFile(string ...$globPatterns)

[](#isfilestring-globpatterns)

The `IsFile` predicate accepts glob patterns in the syntax accepted by `fnmatch`.

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Predicate;

$trace = Backtrace::capture()->reject(Predicate::isFile(
    // rejects everything in `/src/foo.php`
    '/src/foo.php',
    // rejects everything in the `/vendor` directory
    '/vendor/*',
    // rejects files having a `.inc.php` extension
    '*.inc.php',
));
```

### Composing predicates

[](#composing-predicates)

Predicates are composable using the `Predicate::and()`, `Predicate::or()` and `Predicate::not()` predicates.

```
use ju1ius\Footprints\Backtrace;
use ju1ius\Footprints\Frame;
use ju1ius\Footprints\Predicate;

// The following filters out:
// * Foo::bar() and Bar::bar() methods (whether static or not)
// * top-level baz() and qux() functions
$trace = Backtrace::capture()->reject(Predicate::or(
    Predicate::and(
        fn(Frame $frame) => \in_array($frame->class, ['Foo', 'Bar']),
        fn(Frame $frame) => $frame->function === 'bar',
    ),
    Predicate::isFunction('baz', 'qux'),
));
```

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity45

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 ~1 days

Total

2

Last Release

1217d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/db8c537fa479fd389b9ef832345ebf665f767e3ff7c7c345bc0ba4c52b46a22f?d=identicon)[ju1ius](/maintainers/ju1ius)

---

Top Contributors

[![ju1ius](https://avatars.githubusercontent.com/u/218404?v=4)](https://github.com/ju1ius "ju1ius (10 commits)")

### Embed Badge

![Health badge](/badges/ju1ius-footprints/health.svg)

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

###  Alternatives

[symfony/stopwatch

Provides a way to profile code

2.8k387.2M918](/packages/symfony-stopwatch)[fruitcake/laravel-debugbar

PHP Debugbar integration for Laravel

19.1k662.9k29](/packages/fruitcake-laravel-debugbar)[jokkedk/webgrind

Webgrind is a Xdebug profiling web frontend in PHP5. It implements a subset of the features of kcachegrind and installs in seconds and works on all platforms. For quick'n'dirty optimizations it does the job.

3.3k193.0k](/packages/jokkedk-webgrind)[koriym/printo

An object graph visualizer.

1421.8M2](/packages/koriym-printo)[soloterm/dumps

A Laravel command to intercept dumps from your Laravel application.

125285.7k3](/packages/soloterm-dumps)[beyondcode/helo-laravel

HELO Laravel debug helper

90360.1k](/packages/beyondcode-helo-laravel)

PHPackages © 2026

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