andrewdyer/metrics 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

andrewdyer/metrics

Composer 安装命令:

composer require andrewdyer/metrics

包简介

A metrics library for Eloquent applications that calculates strongly typed aggregates over a configurable date range

README 文档

README

A metrics library for Eloquent applications that calculates strongly typed aggregates over a configurable date range.

Latest Stable Version Total Downloads License PHP Version Require

Introduction

This library provides Eloquent-based metric calculations, returning strongly typed result objects for scalar aggregates, time-grouped trends with zero-filled gaps, and categorical breakdowns, all with JSON serialisation support. It works in any PHP application with an Eloquent connection, including outside Laravel via the Capsule manager.

Prerequisites

  • PHP: Version 8.3 or higher is required.
  • Composer: Dependency management tool for PHP.
  • Eloquent ORM: An configured Eloquent connection is required.

Installation

composer require andrewdyer/metrics

Getting Started

1. Set up Eloquent

This library requires an Eloquent connection. In a Laravel application this is configured automatically. Outside of Laravel, bootstrap Eloquent using the Capsule manager:

use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule();

$capsule->addConnection([
    'driver'   => 'mysql',
    'host'     => '127.0.0.1',
    'database' => 'my_database',
    'username' => 'root',
    'password' => '',
    'charset'  => 'utf8',
    'prefix'   => '',
]);

$capsule->setAsGlobal();
$capsule->bootEloquent();

2. Create a metric

Extend Value and implement calculate() to define the query, and getStartDate() / getEndDate() to define the date range:

use AndrewDyer\Metrics\Value;
use AndrewDyer\Metrics\Results\ValueResult;
use DateTimeImmutable;

class TotalNewUsers extends Value
{
    public function calculate(): ValueResult
    {
        return $this->count(User::query());
    }

    public function getStartDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('first day of this month');
    }

    public function getEndDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('last day of this month');
    }
}

Usage

Calculating a metric

Call calculate() on any metric instance to run the query and return a typed result:

$metric = new TotalNewUsers();
$result = $metric->calculate();

$result->getResult(); // e.g. 42

JSON serialisation

All result objects implement JsonSerializable:

json_encode($metric->calculate());
// {"result": 42}

Customising the metric name and description

Override getName() and getDescription() on any metric to provide a human-readable label:

public function getName(): string
{
    return 'Total New Users';
}

public function getDescription(): string
{
    return 'The total number of users who signed up this month.';
}

Rounding

Override getRoundingPrecision() and getRoundingMode() to control how aggregate values are rounded:

public function getRoundingPrecision(): int
{
    return 2;
}

public function getRoundingMode(): int
{
    return PHP_ROUND_HALF_UP;
}

Metric Types

Value

A Value metric calculates a single aggregate over a date range. When the model uses timestamps, the date filter defaults to created_at. When the model does not use timestamps, no date filter is applied unless an explicit $dateColumn is passed.

Count

Returns the number of records within the date range:

$this->count(User::query());

To filter by a specific date column, pass it explicitly:

$this->count(User::query(), null, 'published_at');

On models without timestamps, no date filter is applied unless an explicit column is given:

$this->count(Product::query()); // no date filter — all records returned
$this->count(Product::query(), null, 'released_at'); // filtered by released_at

Sum

Totals the values of a column across all matching records:

$this->sum(User::query(), 'revenue');

Average

Calculates the mean value of a column across all matching records:

$this->average(User::query(), 'revenue');

Minimum

Returns the smallest value of a column within the date range:

$this->min(User::query(), 'revenue');

Maximum

Returns the largest value of a column within the date range:

$this->max(User::query(), 'revenue');

Trend

A Trend metric calculates an aggregate grouped over time at a given frequency. Missing dates within the range are automatically filled with zero values.

When the model uses timestamps, the date column defaults to created_at. When the model does not use timestamps, an explicit $dateColumn must be passed or an InvalidArgumentException is thrown.

Extend Trend and implement calculate(), getStartDate(), getEndDate(), and getFrequency():

use AndrewDyer\Metrics\Trend;
use AndrewDyer\Metrics\Enums\Frequency;
use AndrewDyer\Metrics\Results\TrendResult;
use DateTimeImmutable;

class UserSignupsOverTime extends Trend
{
    public function calculate(): TrendResult
    {
        return $this->count(User::query(), null, 'created_at');
    }

    public function getFrequency(): Frequency
    {
        return Frequency::Monthly;
    }

    public function getStartDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('first day of january this year');
    }

    public function getEndDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('last day of december this year');
    }
}

Calculating the metric returns a keyed array of labels to aggregate values:

$metric = new UserSignupsOverTime();
$result = $metric->calculate();

$result->getResult(); // ['January 2026' => 12, 'February 2026' => 9, ...]

Supported frequencies

Frequency::Daily
Frequency::Weekly
Frequency::Monthly

Count

Tracks how many records fall within each period of the date range:

$this->count(User::query(), null, 'created_at');

Sum

Totals a column's values for each period across the date range:

$this->sum(User::query(), 'revenue', 'created_at');

Average

Calculates the mean value of a column for each period in the range:

$this->average(User::query(), 'revenue', 'created_at');

Minimum

Returns the lowest value of a column recorded within each period:

$this->min(User::query(), 'revenue', 'created_at');

Maximum

Returns the highest value of a column recorded within each period:

$this->max(User::query(), 'revenue', 'created_at');

Partition

A Partition metric calculates an aggregate grouped by a categorical column, returning a key-value breakdown. Results are filtered to the configured date range.

When the model uses timestamps, the date filter defaults to created_at. When the model does not use timestamps, no date filter is applied unless an explicit $dateColumn is passed.

Extend Partition and implement calculate(), getStartDate(), and getEndDate():

use AndrewDyer\Metrics\Partition;
use AndrewDyer\Metrics\Results\PartitionResult;
use DateTimeImmutable;

class UsersByCountry extends Partition
{
    public function calculate(): PartitionResult
    {
        return $this->count(User::query(), 'country');
    }

    public function getStartDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('first day of this year');
    }

    public function getEndDate(): DateTimeImmutable
    {
        return new DateTimeImmutable('today');
    }
}

Calculating the metric returns a keyed array of group labels to aggregate values:

$metric = new UsersByCountry();
$result = $metric->calculate();

$result->getResult(); // ['GB' => 42, 'US' => 31, 'DE' => 14]

Count

Groups records by a column and counts how many fall into each category:

$this->count(User::query(), 'country');

To filter by a specific date column, pass it explicitly:

$this->count(User::query(), 'country', null, 'registered_at');

Sum

Groups records by a column and totals a second column within each group:

$this->sum(User::query(), 'country', 'revenue');

Average

Groups records by a column and calculates the mean of a second column per group:

$this->average(User::query(), 'country', 'revenue');

Database Support

The following database drivers are supported:

Driver Minimum Version
MySQL 5.7+
MariaDB 10.2+
SQLite 3.38.0+
PostgreSQL 9.4+

License

Licensed under the MIT licence and is free for private or commercial projects.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-02