romdh4ne/laravel-querycraft 问题修复 & 功能扩展

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

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

romdh4ne/laravel-querycraft

Composer 安装命令:

composer require romdh4ne/laravel-querycraft

包简介

Find and fix Laravel performance issues automatically

README 文档

README

QueryCraft Logo

A Laravel performance analysis dashboard for detecting N+1 queries, slow queries, missing indexes, and duplicate queries — in real time.

Laravel PHP License Packagist Downloads

✨ Features

  • 🔁 N+1 Detection — catches repeated query patterns caused by missing eager loading
  • 🐢 Slow Query Detection — flags queries exceeding your configured time limit
  • 🗂 Missing Index Detection — identifies full table scans using MySQL EXPLAIN
  • 📋 Duplicate Query Detection — finds identical queries (including bindings) fired multiple times
  • 📍 Source Location — shows the exact file and line number in your app that triggered the issue
  • 💯 Performance Score — grades your endpoint from 0–100 with a letter grade (A–F)
  • 🛠 Live Config Panel — toggle detectors and adjust thresholds from the dashboard UI
  • 🌙 Dark Mode — built-in dark/light mode toggle
  • 🚨 500 Error Inspector — displays full exception details with app-only stack trace
  • ⌨️ Artisan Command — analyze endpoints directly from your terminal with full body and header support

📦 Installation

1. Require the package via Composer

composer require romdh4ne/laravel-querycraft

2. Publish the config file

php artisan vendor:publish --tag=querycraft-config

3. Publish the assets (logo, favicon)

php artisan vendor:publish --tag=querycraft-assets

4. Publish the views (optional — only if you want to customize the UI)

php artisan vendor:publish --tag=querycraft-views

5. Clear caches

php artisan config:clear
php artisan view:clear

6. Visit the dashboard

http://your-app.test/querycraft

🖥 Web Dashboard

Opening the dashboard

http://your-app.test/querycraft

QueryCraft Dashboard

Or with a custom route prefix set in .env:

http://your-app.test/your-custom-prefix

Analyzing an endpoint

  1. Enter your endpoint URL (e.g. /api/users)
  2. Select the HTTP method (GET, POST, PUT, PATCH, DELETE)
  3. Optionally add custom headers (e.g. Authorization: Bearer token)
  4. Optionally add a JSON request body for POST/PUT requests
  5. Click Analyze Request

QueryCraft fires an internal request to your endpoint, collects all queries, runs them through all detectors, and displays the results instantly.

Reading the results

Element Description
Score card 0–100 performance grade with letter (A–F) and emoji indicator
Query count Total number of queries executed by the endpoint
Total time Combined execution time of all queries in milliseconds
Issue cards Each problem with severity, stats, source location and fix suggestion
Source Location Exact file path and line number in your app (vendor files filtered out)
All Queries Collapsible list of every query fired with individual execution time

500 Error Inspector

When your endpoint crashes, QueryCraft catches it and displays:

  • Exception class (e.g. ErrorException, QueryException)
  • Error message
  • Exact file and line number in your app where it crashed
  • Stack trace showing only your app files — no vendor noise
  • Number of queries captured before the crash

Set APP_DEBUG=true in your .env for full exception details.

Client Error Display

When your endpoint returns a 4xx response (e.g. 422 validation error, 404), QueryCraft shows:

  • The HTTP status code
  • The error message returned by your API
  • Suggestions for similar routes if 404

Config Panel

Click the ⚙️ icon in the top-right header to open the config panel:

  • Toggle each detector on/off individually
  • Adjust thresholds using sliders
  • Tune score weights (must total 100%)
  • Click Save — changes are written to your .env immediately
  • Click Reset to restore all defaults

⌨️ Artisan Command

Analyze endpoints directly from your terminal without opening a browser.

Signature

php artisan querycraft:analyze
    {--url=         : The endpoint URL to analyze}
    {--method=GET   : HTTP method (GET, POST, PUT, PATCH, DELETE)}
    {--user=        : Authenticate as a specific user ID}
    {--show-queries : Print all executed queries in the output}
    {--body=        : JSON body as an inline string}
    {--body-file=   : Path to a JSON file to use as the request body}
    {--header=*     : Custom headers in Key:Value format (repeatable)}

Examples

# Simple GET
php artisan querycraft:analyze --url=/users

# With authentication
php artisan querycraft:analyze --url=/dashboard --user=1

# POST with inline JSON body
php artisan querycraft:analyze --url=/api/posts --method=POST \
  --body='{"title":"Hello","body":"World","category_id":1}'

# POST with many fields — use --body-file to keep it clean
php artisan querycraft:analyze --url=/api/orders --method=POST \
  --body-file=./payload.json

# PUT with body and auth
php artisan querycraft:analyze --url=/api/users/1 --method=PUT --user=1 \
  --body='{"name":"John","email":"john@example.com"}'

# With custom headers
php artisan querycraft:analyze --url=/api/secret \
  --header="Authorization:Bearer your-token" \
  --header="X-Team-Id:42"

# Everything combined
php artisan querycraft:analyze --url=/api/orders --method=POST --user=1 \
  --body-file=./payload.json \
  --header="X-Source:querycraft" \
  --show-queries

Sending a large body with --body-file

When your request has many fields, create a payload.json file instead of cramming everything inline:

{
  "customer_id": 5,
  "shipping_address": {
    "street": "123 Main St",
    "city": "Paris",
    "zip": "75001"
  },
  "items": [
    { "product_id": 1, "qty": 2, "price": 29.99 },
    { "product_id": 3, "qty": 1, "price": 49.99 }
  ],
  "coupon": "SAVE10",
  "notes": "Leave at door"
}

Then run:

php artisan querycraft:analyze --url=/api/orders --method=POST \
  --body-file=./payload.json --user=1 --show-queries

Use --body for small payloads. Use --body-file for large or complex payloads — it avoids shell escaping issues and is much easier to read and reuse.

Example output

🔍 Analyzing: GET /users

✅ Response: 200

📊 Summary:
+----------------+----------+
| Metric         | Value    |
+----------------+----------+
| Total Queries  | 23       |
| Total Time     | 182.5 ms |
| Avg Query Time | 7.93 ms  |
| Response Status| 200      |
+----------------+----------+

⚠️  Found 2 issue(s):

🔴 Issue #1: N+1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Severity: HIGH
Occurrences: 20
Total Time: 140ms
Location: /app/Http/Controllers/UserController.php:45

Query:
  select * from `companies` where `id` = ?

💡 Suggestion:
  Add eager loading: ->with('company')

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚡ Performance Score: 62/100 (Grade: D) 🟠
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎯 Top Improvements:
  • Too many queries (+25 points)
  • 2 performance issues detected (+20 points)

If your endpoint requires authentication, pass --user=1 to run as a specific user. QueryCraft calls auth()->login($user) before firing the request.

⚙️ Configuration

After publishing, the config file is at config/querycraft.php. All values can be overridden via .env:

# Enable or disable the package entirely
QUERY_DEBUGGER_ENABLED=true

# Detectors — toggle individually
QUERYCRAFT_DETECTOR_N1=true
QUERYCRAFT_DETECTOR_SLOW_QUERY=true
QUERYCRAFT_DETECTOR_MISSING_INDEX=true
QUERYCRAFT_DETECTOR_DUPLICATE_QUERY=true

# Thresholds
QUERY_DEBUGGER_N1_THRESHOLD=5        # Flag N+1 after this many repetitions (default: 5)
QUERY_DEBUGGER_SLOW_THRESHOLD=100    # Flag queries slower than this in ms (default: 100)
QUERYCRAFT_DUPLICATE_COUNT=2         # Flag duplicates after this many repeats (default: 2)

# Score weights — must total 100
QUERYCRAFT_WEIGHT_QUERY_COUNT=40
QUERYCRAFT_WEIGHT_QUERY_TIME=30
QUERYCRAFT_WEIGHT_ISSUES=30

# Dashboard route prefix (default: querycraft)
QUERYCRAFT_DASHBOARD_ROUTE=querycraft

Full config reference

// config/querycraft.php
return [
    'enabled' => env('QUERY_DEBUGGER_ENABLED', true),

    'detectors' => [
        'n1'             => env('QUERYCRAFT_DETECTOR_N1', true),
        'slow_query'     => env('QUERYCRAFT_DETECTOR_SLOW_QUERY', true),
        'missing_index'  => env('QUERYCRAFT_DETECTOR_MISSING_INDEX', true),
        'duplicate_query'=> env('QUERYCRAFT_DETECTOR_DUPLICATE_QUERY', true),
    ],

    'thresholds' => [
        'n1_count'        => env('QUERY_DEBUGGER_N1_THRESHOLD', 5),
        'slow_query_ms'   => env('QUERY_DEBUGGER_SLOW_THRESHOLD', 100),
        'duplicate_count' => env('QUERYCRAFT_DUPLICATE_COUNT', 2),
    ],

    'weights' => [
        'query_count' => env('QUERYCRAFT_WEIGHT_QUERY_COUNT', 40),
        'query_time'  => env('QUERYCRAFT_WEIGHT_QUERY_TIME', 30),
        'issues'      => env('QUERYCRAFT_WEIGHT_ISSUES', 30),
    ],
];

Tip: All settings can also be changed from the dashboard ⚙️ config panel — changes are saved directly to your .env.

🔬 How Detectors Work

🔁 N+1 Detection

Normalizes every query (replaces values with ?) and groups them by pattern. If the same pattern fires more than n1_count times, it's flagged. The exact file and line in your app that triggered the repeated query is shown.

Example:

// ❌ N+1 — fires one query per user
$users = User::all();
foreach ($users as $user) {
    echo $user->company->name;
}

// ✅ Fix — one query total
$users = User::with('company')->get();
Count Severity
5–10× low
10–20× medium
20–50× high
50×+ critical

🐢 Slow Query Detection

Flags any query exceeding slow_query_ms milliseconds (default: 100ms). Automatically suggests a fix based on the query structure.

Time Severity
> 200ms low
> 500ms medium
> 1000ms high
> 1000ms critical

Suggestions shown:

  • SELECT * → use specific columns
  • ORDER BY without LIMIT → add a limit
  • LIKE queries → consider full-text search
  • COUNT(*) on large tables → consider caching

🗂 Missing Index Detection

Runs MySQL EXPLAIN on each query and flags full table scans, filesorts, and temporary table usage.

Triggers:

  • type = ALL with more than 1,000 rows examined
  • Extra contains Using filesort
  • Extra contains Using temporary

Example:

User::where('email', $email)->first(); // no index on email

// Fix — in a migration:
$table->index('email');
$table->index(['status', 'created_at']); // composite
Rows examined Severity
> 1,000 low
> 10,000 medium
> 100,000 high
> 100,000 critical

📋 Duplicate Query Detection

Creates an md5 fingerprint of sql + bindings. If the exact same query with the same parameter values runs more than duplicate_count times (default: 2), it's flagged.

Example:

// ❌ Duplicate — same query + same values fired twice
$settings = Setting::all();
// ... somewhere else in the same request ...
$settings = Setting::all();

// ✅ Fix
$settings = Cache::remember('settings', 3600, fn() => Setting::all());

💯 Performance Score

Calculated as a weighted average across three dimensions:

Dimension Default Weight Description
Query Count 40% Fewer queries = higher score
Query Time 30% Faster total time = higher score
Issues Found 30% Fewer/lower severity issues = higher score
Score Grade Status
90–100 A 🟢 Excellent
80–89 B 🟡 Good
70–79 C 🟡 Acceptable
60–69 D 🟠 Below average
0–59 F 🔴 Critical issues

Weights are configurable from the dashboard config panel or via .env.

🔒 Security

QueryCraft is intended for local development only. Always disable it in production:

# .env.production
QUERY_DEBUGGER_ENABLED=false

🔄 Updating

composer update romdh4ne/laravel-querycraft
php artisan vendor:publish --tag=querycraft-views --force
php artisan vendor:publish --tag=querycraft-assets --force
php artisan config:clear
php artisan view:clear

🗑 Uninstalling

composer remove romdh4ne/laravel-querycraft
rm config/querycraft.php
rm -rf resources/views/vendor/querycraft
rm -rf public/vendor/querycraft
# Remove QUERYCRAFT_* and QUERY_DEBUGGER_* lines from your .env

🤝 Contributing

Setup

git clone https://github.com/YOUR_USERNAME/laravel-querycraft.git
cd laravel-querycraft
composer install

Local test app (separate project)

In a separate Laravel app, add to composer.json:

"repositories": [
    {
        "type": "path",
        "url": "../laravel-querycraft",
        "options": { "symlink": true }
    }
]

Then:

composer require romdh4ne/laravel-querycraft:@dev
php artisan vendor:publish --tag=querycraft-config
php artisan vendor:publish --tag=querycraft-assets
php artisan config:clear
php artisan serve

Visit http://localhost:8000/querycraft. Any change you make in the package reflects instantly thanks to the symlink.

📄 License

QueryCraft is open-source software licensed under the MIT license.

👨‍💻 Author

Made by Romdh4ne

If this package helps you, give it a ⭐ on GitHub!

romdh4ne/laravel-querycraft 适用场景与选型建议

romdh4ne/laravel-querycraft 是一款 基于 Blade 开发的 Composer 扩展包,目前已累计 23 次下载、GitHub Stars 达 22, 最近一次更新时间为 2026 年 02 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「database」 「performance」 「optimization」 「laravel」 「queries」 「n-plus-one」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 romdh4ne/laravel-querycraft 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 romdh4ne/laravel-querycraft 我们能提供哪些服务?
定制开发 / 二次开发

基于 romdh4ne/laravel-querycraft 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

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

GitHub 信息

  • Stars: 22
  • Watchers: 1
  • Forks: 0
  • 开发语言: Blade

其他信息

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