DbCollector
API reference › Debug › collectors › DbCollector
Captures every database query emitted during the request for the Database panel.
Hooks every DB connection so each prepared statement records its row count, calculates per-query timings from the profile log, and exposes the totals the exported summary adopts (query count, excessive callers).
The hook installs PDO::ATTR_STATEMENT_CLASS on each profiled connection, an attribute PDO rejects on
persistent instances, so persistent PDO connections are not supported while the collector is active.
Properties
Section titled “Properties”| Property | Type | Description | Defined by |
|---|---|---|---|
$db | string | Application component id of the DB connection whose prepared statements are instrumented. Default: 'db'. | DbCollector |
$dbEventNames | list<string> | Profile log categories scanned for query timings. Default: ['yii\. | DbCollector |
$excessiveCallerThreshold | int| | Number of DB calls the same backtrace can make before being flagged as an “Excessive Caller”. null disables the check. Default: null. | DbCollector |
$ignoredPathsInBacktrace | list<string> | Paths whose backtrace frames are skipped when determining the “Caller”. Default: []. | DbCollector |
$module | yii\| | Debug module supplying the log target and sibling collectors, assigned by the module on registration. Default: null. | Collector |
Methods
Section titled “Methods”| Method | Description | Defined by |
|---|---|---|
calculateTimings() | Calculates and caches the per-query timings for the request, dropping backtrace frames that match $ignoredPathsInBacktrace and tagging each timing with a stable hash of its remaining trace. | DbCollector |
capture() final | Encodes the typed snapshot built by the subclass into the payload persisted for the panel. | Collector |
countCallerCals() | Counts how many times the same backtrace originated a DB query. | DbCollector |
getExcessiveCallers() | Returns the call counts for backtraces that issued at least $excessiveCallerThreshold queries. | DbCollector |
getExcessiveCallersCount() | Returns the number of distinct backtraces flagged as excessive callers. | DbCollector |
getProfileLogs() | Returns the profile log entries scanned for query timings (categories listed in $dbEventNames). | DbCollector |
id() | Returns the stable ID pairing this collector with the Database panel. | DbCollector |
instrument() | Installs the DebugPdoStatement class on every DB connection so each prepared statement records its rowCount(). | DbCollector |
shutdown() final | Deactivates the collector once, releasing any subscription created by start(). | Collector |
startup() final | Activates the collector once at the start of the request lifecycle. | Collector |
getLogMessages() protected | Returns the accumulated log messages, optionally filtered by level, category, and exclusion lists. | Collector |
getLogTarget() protected | Returns the initialized log target of the owning debug module. | Collector |
isStarted() protected | Returns whether the collector is active for the current request. | Collector |
snapshot() protected | Resolves the logger timings into typed query rows and snapshots them. | DbCollector |
start() protected | Resets the per-request caches, binds the row-count window to the current request tag, and installs the statement hook through instrument() when the module has not already done so. | DbCollector |
stop() protected | Detaches the class-level after-open listener and clears the per-request caches, so a reused worker process starts clean. | DbCollector |
Property details
Section titled “Property details”$ignoredPathsInBacktrace
Section titled “$ignoredPathsInBacktrace ”public list<string> $ignoredPathsInBacktrace = []Paths whose backtrace frames are skipped when determining the “Caller”.
Yii framework files are ignored by default. Path aliases are resolved through Yii::getAlias().
Method details
Section titled “Method details”calculateTimings()
Section titled “calculateTimings() ”public function calculateTimings(): array<int, array{info: string, category: string, timestamp: float, trace: array<int, array<string, mixed>>, level: int, duration: float, memory: int, memoryDiff: int, traceHash: string}>Calculates and caches the per-query timings for the request, dropping backtrace frames that match
$ignoredPathsInBacktrace and tagging each timing with a stable hash of its remaining trace.
Returns
array<int, array{info: string, category: string, timestamp: float, trace: array<int, array<string, mixed>>, level: int, duration: float, memory: int, memoryDiff: int, traceHash: string}>: Timings indexed sequentially, each carrying the SQL token, category, capture timestamp, trace, nesting level, duration, memory snapshots, and trace hash.
countCallerCals()
Section titled “countCallerCals() ”public function countCallerCals(): array<string, int>Counts how many times the same backtrace originated a DB query.
Returns
array<string, int>: Call counts indexed by the backtrace hash of the caller.
getExcessiveCallers()
Section titled “getExcessiveCallers() ”public function getExcessiveCallers(): array<string, int>Returns the call counts for backtraces that issued at least $excessiveCallerThreshold queries.
Returns
array<string, int>: Call counts indexed by the backtrace hash of each excessive caller; empty when the check is disabled.
getExcessiveCallersCount()
Section titled “getExcessiveCallersCount() ”public function getExcessiveCallersCount(): intReturns the number of distinct backtraces flagged as excessive callers.
Returns
int: Number of distinct backtraces that issued at least the threshold number of queries.
getProfileLogs()
Section titled “getProfileLogs() ”public function getProfileLogs(): list<yii\debug\collectors\LogTuple>Returns the profile log entries scanned for query timings (categories listed in $dbEventNames).
Returns
list<yii\debug\collectors\LogTuple>: Profile log entries in capture order.
public function id(): stringReturns the stable ID pairing this collector with the Database panel.
Returns
string: Stable collector ID.
instrument()
Section titled “instrument() ”public function instrument(): voidInstalls the DebugPdoStatement class on every DB connection so each prepared statement records its
rowCount().
The hook is applied through PDO::ATTR_STATEMENT_CLASS rather than Connection::$commandClass, since the
latter is not exposed by every Yii 2 fork. Connections already instantiated and open are hooked immediately; a
class-level Connection::EVENT_AFTER_OPEN listener covers every connection opened later in the request,
whatever its component id. Instrumenting them all keeps the recorded counts aligned with the profile timings,
which the logger collects from every profiled connection.
Module::initCollectors() calls this while the debugger bootstraps, ahead of the panels, so
queries issued by a panel constructor are counted as well; that first call also opens the row-count window.
Reinstallation is skipped while the hook is active, so the counts recorded so far survive start().
snapshot()
Section titled “snapshot() ”protected function snapshot(): PHPForge\Debug\Panel\Db\DbSnapshot|nullResolves the logger timings into typed query rows and snapshots them.
Returns
PHPForge\Debug\Panel\Db\DbSnapshot|null: Captured query payload; null when the collector never started.
start()
Section titled “start() ”protected function start(): voidResets the per-request caches, binds the row-count window to the current request tag, and installs the statement
hook through instrument() when the module has not already done so.
The counts are discarded only when they belong to another request, so the collector survives being restarted
inside one request: a handled exception makes the logger flush twice, and each flush drives
LogTarget::export() through a full shutdown/startup cycle.
stop()
Section titled “stop() ”protected function stop(): voidDetaches the class-level after-open listener and clears the per-request caches, so a reused worker process starts clean.
The recorded row counts stay in place: they are discarded by the next start() that belongs to a different
request, which keeps them readable when the same request captures more than once.