Download the PHP package karimalihussein/laravel-query-sentinel without Composer

On this page you can find all versions of the php package karimalihussein/laravel-query-sentinel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-query-sentinel

Laravel Query Sentinel

CI Security

Enterprise-grade SQL performance diagnostics engine for Laravel. Runs EXPLAIN ANALYZE, scores queries across 5 weighted dimensions, detects 10 SQL anti-patterns, synthesizes index recommendations, estimates memory pressure under concurrency, tracks regressions over time, and simulates hypothetical indexes — all from a single diagnose() call or an interactive Artisan command.

Table of Contents


Requirements

Installation

Development only — Install as a dev dependency. It will not be present in production when you run composer install --no-dev.

The service provider is auto-discovered. To publish the configuration:

Two facades are registered automatically:

Quick Start


Configuration

After publishing, edit config/query-diagnostics.php:

Environment Variables

Variable Default Description
QUERY_SENTINEL_DRIVER mysql Database driver (mysql, pgsql)
QUERY_SENTINEL_CONNECTION null Database connection name
QUERY_SENTINEL_DIAGNOSTICS_ENABLED true Enable attribute-based profiling
QUERY_SENTINEL_SAMPLE_RATE 1.0 Global profiling sample rate (0.0-1.0)
QUERY_SENTINEL_THRESHOLD_MS 0 Global minimum cumulative time to log
QUERY_SENTINEL_FAIL_ON_CRITICAL false Throw exception on critical findings

Analysis Modes

Mode 1: Raw SQL Analysis

Analyze a raw SQL string. Validated for safety (only SELECT/WITH), sanitized, and run through EXPLAIN ANALYZE.

Safety: Only read-only SQL is accepted. Destructive statements throw UnsafeQueryException.

Mode 2: Query Builder / Eloquent Analysis

Analyze a Builder instance without executing it. SQL and bindings are extracted via toSql() / getBindings().

Mode 3: Closure Profiling

Profile all database queries inside a closure. Captures via DB::listen(), wraps in transaction (rolled back), and analyzes each SELECT.

Safety: Transaction is always rolled back. No writes persist.

Mode 4: Class Method Profiling

Profile a class method resolved from the Laravel container.

Mode 5: Full Deep Diagnostics

Run the full 22-step diagnostic pipeline with all deep analyzers.


Interactive Query Scanning

The query:scan command discovers methods annotated with #[DiagnoseQuery], presents an interactive list, and runs full EXPLAIN ANALYZE diagnostics on the selected query builder.

Setting Up DiagnoseQuery

Add the #[DiagnoseQuery] attribute to methods that return a Query Builder:

Running the Scanner

Example interactive session:

How It Works

  1. Scan — Finder locates PHP files containing DiagnoseQuery in configured paths (app/, Modules/)
  2. Reflect — PHP Reflection discovers annotated methods and extracts metadata
  3. Select — Developer picks a method from the interactive list
  4. Resolve — Class is resolved from the Laravel container (DI works normally)
  5. Execute — Method is called inside DB::beginTransaction() to get the Builder
  6. Rollback — Transaction is immediately rolled back (no side effects)
  7. Extract — SQL and bindings are extracted from the Builder via toSql() / getBindings()
  8. Diagnose — Full Engine::diagnose() pipeline runs EXPLAIN ANALYZE + all deep analyzers
  9. Report — Full diagnostic report is rendered to the console

Writing Diagnosable Methods

The annotated method must:

If your production method takes parameters, create a dedicated diagnosis method:

Configure which directories to scan:


Automatic Profiling with Attributes

The #[QueryDiagnose] attribute enables zero-code-change runtime profiling. Place it on any controller or service method to automatically capture, analyze, and log query performance during normal execution.

Two different attributes for two different purposes:

  • #[DiagnoseQuery] — Interactive CLI scanning (returns a Builder, used with query:scan)
  • #[QueryDiagnose] — Runtime profiling (captures queries during execution, logs results)

Controller Profiling (Middleware)

Register the middleware:

Apply to routes:

Add the attribute:

Methods without the attribute pass through with zero overhead.

Service Class Profiling (Container Proxy)

Register service classes in config:

Add attributes to methods:

When the service is resolved from the container, it is wrapped in a MethodInterceptor proxy that intercepts attributed methods and forwards everything else directly.

Sampling and Thresholds

Sampling controls how often profiling activates:

Effective rate: min(methodRate, globalRate).

Thresholds filter logging noise:

Effective threshold: max(methodThreshold, globalDefault).

Attribute Param Config Key Combination Logic
sampleRate diagnostics.global_sample_rate min(method, global) — most restrictive wins
thresholdMs diagnostics.default_threshold_ms max(method, global) — highest bar wins

Fail on Critical

Throw PerformanceViolationException on critical performance issues:

Triggers when: worst grade is D/F, any query > 500ms, full table scan, or N+1 detected.

Structured Logging

Profiled invocations are logged as structured JSON:

Log levels: error (D/F), warning (C or N+1), info (A/B).


Console Commands

query:diagnose — Analyze Raw SQL

query:scan — Interactive Builder Diagnosis

Console Report Output

CI Integration


Deep Diagnostic Features

When using Engine::diagnose() or query:diagnose / query:scan, the full 22-step pipeline runs automatically.

22-Step Analysis Pipeline

Step Phase What It Does
1 Base EXPLAIN ANALYZE + parse metrics + score + rules
2 Environment Collect MySQL config (buffer pool, InnoDB, cache warmth)
3 Execution Profile Nested loop depth, B-tree depths, physical reads, complexity
4 Index Cardinality Per-table index statistics and selectivity
5 Cardinality Drift Estimated vs actual rows divergence
6 Join Analysis Join strategy, fan-outs, join order
7 Anti-Patterns 10 SQL anti-patterns (SELECT *, leading wildcard, etc.)
8 Index Synthesis ERS-ordered composite index recommendations
9 Memory Pressure Sort/join/temp buffers, concurrency-adjusted footprint
10 Concurrency Risk Lock scope, deadlock risk, contention scoring
11 Plan Stability Plan flip risk, volatility score, optimizer hints
12 Regression Safety Implicit type conversions, collation mismatches
13 Confidence Score 8-factor trustworthiness rating
14 Regression Baselines Score/time/rows changes vs historical baseline
15 Hypothetical Indexes Before/after EXPLAIN simulation (local/testing)
16 Workload Patterns Repeated exports, API bursts, large transfers
17 Complexity Scan + sort complexity classification
18 Explain Why Human-readable insight (index choice, filesort reason, etc.)
19 Root-cause suppression Remove misleading generic findings
20 Finding deduplication Merge overlapping recommendations
21 Confidence gating Downgrade severity when confidence is low
22 Consistency validation Log-only internal coherence check

Cardinality Drift Detection

Compares optimizer row estimates against actual rows from EXPLAIN ANALYZE. Large deviations indicate stale statistics.

Config: cardinality_drift.warning_threshold (default 0.5), cardinality_drift.critical_threshold (default 0.9).

Anti-Pattern Detection

Static SQL analysis for 10 common performance anti-patterns:

Pattern Severity Why It Matters
SELECT * Warning Prevents covering index optimization
Functions on indexed columns Warning Breaks index usage (e.g., WHERE YEAR(created_at) = 2026)
Excessive OR chains Warning Inefficient range scans (threshold: 3+)
Correlated subqueries Warning Executes once per outer row
NOT IN with subquery Warning NULL handling issues, anti-join problems
Leading wildcard LIKE Warning Forces full table scan (LIKE '%term')
Missing LIMIT on large result Optimization Unbounded memory consumption
ORDER BY RAND() Warning O(n log n) full sort
Redundant DISTINCT Optimization Unnecessary with PRIMARY/UNIQUE key
Implicit type conversion Warning Prevents index usage

Config: anti_patterns.or_chain_threshold (default 3), anti_patterns.missing_limit_row_threshold (default 10000).

Index Synthesis

Recommends optimal composite indexes using the ERS principle (Equality, Range, Sort, Select columns):

Config: index_synthesis.max_recommendations (default 3), index_synthesis.max_columns_per_index (default 5).

Confidence Scoring

Attaches a trustworthiness score (0-1.0) to the analysis based on 8 weighted factors:

Factor Weight Measures
Estimation accuracy 25% 1.0 minus composite drift score
Sample size 20% Actual rows (1.0 at 1000+ rows)
EXPLAIN ANALYZE available 15% 1.0 if supported, 0.3 otherwise
Cache warmth 10% 1.0 if buffer pool > 50% utilized
Statistics freshness 10% Ratio of non-stale tables
Plan stability 10% 1.0 if stable, 0.5 if flip risk
Query complexity 5% 0.7 if > 3 joins
Driver capabilities 5% Full support = 1.0

Labels: high (90%+), moderate (70-89%), low (50-69%), unreliable (<50%).

When confidence is low, findings are automatically downgraded (Critical to Warning at <70%, Critical/Warning down one level at <50%).

Concurrency Risk Analysis

Evaluates lock contention, deadlock potential, and isolation impact:

Memory Pressure Analysis

Estimates query memory footprint under concurrency:

Network pressure levels: LOW (<50MB), MODERATE (50-100MB), HIGH (100-200MB), CRITICAL (>200MB).

Regression Baselines

Tracks query performance over time. Each diagnose() call saves a snapshot. Subsequent runs compare against the baseline to detect regressions.

Smart regression detection:

Config: regression.score_warning_threshold (default 10%), regression.time_warning_threshold (default 50%).

Hypothetical Index Simulation

Creates temporary indexes, runs EXPLAIN, compares before/after, then drops them. Only runs in local/testing environments.

Improvement levels: significant (access type improved), moderate (>50% row reduction), marginal (>10%), none.

Workload Pattern Detection

Tracks query execution patterns over time to detect systemic issues:

Pattern Severity Triggers When
REPEATED_FULL_EXPORT Critical 100K+ row query executed 10+ times with 3+ full exports
HIGH_FREQUENCY_LARGE_TRANSFER Warning >50MB network transfer, 10+ executions
API_MISUSE_BURST Warning 5+ executions within 60 seconds

Config: workload.frequency_threshold (default 10), workload.export_row_threshold (default 100K).

Plan Stability Analysis

Detects optimizer plan flip risk from estimation deviations:


Report Reference

Report Object (Single Query)

Returned by analyzeSql() and analyzeBuilder():

DiagnosticReport Object (Full Diagnostics)

Returned by diagnose():

ProfileReport Object (Multiple Queries)

Returned by profile() and profileClass():

Grading System

Grade Score Range Meaning
A+ 98 - 100 Perfect — optimal execution plan
A 90 - 97 Excellent — well-optimized query
B 75 - 89 Good — minor optimization opportunities
C 50 - 74 Fair — notable performance issues
D 25 - 49 Poor — significant performance problems
F 0 - 24 Critical — severe performance issues

Score modifiers:

Scoring Components

Component Default Weight What It Measures
execution_time 30% Query execution speed (3-regime model)
scan_efficiency 25% Ratio of rows returned vs rows examined
index_quality 20% Index usage, covering index, access type
join_efficiency 15% Join type quality and nested loop depth
scalability 10% Complexity class projection at scale

Metrics Extracted

Metric Type Description
execution_time_ms float EXPLAIN ANALYZE execution time
rows_examined int Total rows read from storage
rows_returned int Rows returned to client
selectivity_ratio float rows_examined / rows_returned
complexity string O(1), O(log n), O(n), O(n log n), O(n²)
has_table_scan bool Full table scan detected
has_filesort bool External sort operation
has_temp_table bool Temporary table created
has_disk_temp bool Temp table spilled to disk
has_weedout bool Semi-join weedout optimization
has_index_merge bool Index merge optimization
has_covering_index bool Query served entirely from index
has_early_termination bool LIMIT-optimized early stop
is_index_backed bool Uses any index
is_intentional_scan bool Full dataset retrieval (no WHERE, no LIMIT)
indexes_used string[] Index names used
tables_accessed string[] Table names accessed

Built-in Rules

Rule Severity Triggers When
FullTableScanRule Critical Full table scan on > 10,000 rows
NoIndexRule Critical No index used at all
TempTableRule Critical/Warning Temporary table created (critical if on disk)
QuadraticComplexityRule Critical O(n^2) complexity detected
DeepNestedLoopRule Warning Nested loop depth exceeds threshold (default 4)
StaleStatsRule Warning Table statistics appear outdated
LimitIneffectiveRule Warning LIMIT clause doesn't prevent full scan
IndexMergeRule Info Index merge optimization detected
WeedoutRule Info Semi-join weedout strategy detected

Custom Rules

Extend BaseRule:

Register in config:


Extension Points

Custom Drivers

Implement DriverInterface for other databases:

Custom Scoring Engine

Implement ScoringEngineInterface:


Architecture

Design Principles


Testing


License

MIT


All versions of laravel-query-sentinel with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/console Version ^10.0||^11.0||^12.0
illuminate/contracts Version ^10.0||^11.0||^12.0
illuminate/database Version ^10.0||^11.0||^12.0
illuminate/support Version ^10.0||^11.0||^12.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package karimalihussein/laravel-query-sentinel contains the following files

Loading the files please wait ...