rudolfbruder/laravel-snip 问题修复 & 功能扩展

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

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

rudolfbruder/laravel-snip

Composer 安装命令:

composer require rudolfbruder/laravel-snip

包简介

A dd()-style snipping tool for Laravel — capture values during a request and view them on-page in an admin-only panel.

README 文档

README

laravel-snip

laravel-snip

A dd() that does not die.

Drop a snip($order) anywhere in your Laravel app and the value shows up in an admin-only on-page panel — no log files to grep, no debugger to attach, no broken page. Works the same on full HTML responses, Livewire components, and Inertia SPA navigations.

snip($order, 'before-payment');

Open the page as an authorised user, hit Cmd+K (or Ctrl+K), and you have a Horizon-style panel pinned to the corner of the page with everything you captured during the request — values, timings, milestones, dataLayer events, cache keys, and queue state.

Safe to leave in production. Gated, redacted, never cached.

Why not just dd() or Debugbar?

vs. dd() / dump()

dd() dump() snip()
Breaks the page Yes — terminates the response Sometimes — prints into the HTML No — value rendered in a side panel
Survives a redirect No — the response is killed before the redirect runs No — output lost on the next request Yes — captures are flashed across the redirect and shown on the landing page
Works in API / JSON / Inertia XHR responses No — corrupts the response body No — same Yes — shipped via Inertia shared prop, or carried across redirects until a panel-renderable response
Multiple values per request One, then dead Yes, inline Yes — and grouped by label, with timings and milestones in their own tabs
Inspect later No — gone after the page No — gone after the page Yes — pin the panel open, navigate freely, keep capturing
Safe to leave in prod Never Never Yes — gated, redacted, no-store cached

vs. Laravel Debugbar / Telescope / Clockwork

Debugbar / Telescope / Clockwork snip()
Production-safe Discouraged or off-limits — they capture for every request and store a lot Yes — recording short-circuits for non-gated users before any backtrace, dump, or serialise runs
Per-user gating Coarse (env / IP / config flag) Fine-grained Laravel Gate::define('viewSnip', …) — pick any user predicate
Performance hit on the hot path Always-on instrumentation Zero cost for non-gated users; ~one gate check per request for gated users
What gets recorded The whole request (queries, jobs, mail, views, etc.) — opinionated Whatever you write snip(…) against — surgical, intent-driven
Storage Database / files / external services to clean up Session flash + in-memory; nothing to migrate, nothing to expire
Setup Migrations, providers, dashboards, retention composer require + one gate closure

The trade is deliberate. Debugbar / Telescope answer "what happened in this request?". snip() answers "what is this value right now?" — the same question dd() answers, with none of the costs of dd().

What it carries over from a production-safe tool like Horizon: scoped per-request state, an admin-only gate, private cache headers on every injected response, and zero impact on users who do not match the gate.

Installation

composer require rudolfbruder/laravel-snip
php artisan snip:install

The installer publishes config/snip.php, copies the frontend bundle to public/vendor/snip/, and creates app/Providers/SnipServiceProvider.php where you define who can see the panel.

Register the provider:

// Laravel 10 — config/app.php
App\Providers\SnipServiceProvider::class,

// Laravel 11+ — bootstrap/providers.php
App\Providers\SnipServiceProvider::class,

After every composer update rudolfbruder/laravel-snip, refresh the bundle:

php artisan snip:publish

Who can see the panel

Edit app/Providers/SnipServiceProvider.php:

protected function gate(): void
{
    Gate::define('viewSnip', function ($user = null) {
        return $user?->is_admin === true;
    });
}

Without an override, only app()->environment('local') sees the panel. Unauthorised users never receive captured data — the middleware never injects, the Inertia share callback returns null, and the recording API short-circuits before any backtrace or serialisation runs.

Laravel support

Three top-level helpers cover most use:

snip($value, 'label');     // capture a value
snip_time('elastic');      // record an elapsed-time entry
snip_here('reached-step-2'); // drop a milestone breadcrumb

Or use the facade:

use RudolfBruder\LaravelSnip\Facades\Snip;

Snip::add($order, 'order');
Snip::start('payment');
$result = $gateway->charge($order);
Snip::timing('payment');
Snip::milestone('payment-confirmed');

Reload the page. The panel pill appears bottom-right; click it or press Cmd+K / Ctrl+K.

That is the entire surface area. No bootstrapping, no middleware to register, no <script> tags to add — the package wires everything into the framework on install.

Inertia support

Works out of the box. The package detects Inertia and registers a shared _snip prop so every visit — initial HTML and subsequent SPA XHR navigations — carries the current request's captures.

// Inertia controller
public function show(Order $order)
{
    snip($order, 'order');
    snip_time('elastic-query');

    return Inertia::render('Orders/Show', [...]);
}

Captures appear in the panel without a full page reload. When the panel is already open and you navigate to another page via <Link>, the panel re-renders with the new request's data.

For Inertia POST → 303 → GET XHR flows (form submissions, destroy actions), captures recorded in the POST handler are flashed to the session and replayed on the next request, so nothing gets lost across the redirect.

Tabs

The panel has six tabs. Each tab is independent — you only see the ones with data, or all of them when display_mode = always.

Snips

Inspect any PHP value as a typed, collapsible tree.

snip($order, 'order');
snip(['user' => $user, 'cart' => $cart], 'checkout-state');
snip(Order::with('items')->find($id));

Returns the value unchanged so it can be inlined inside expressions:

return snip(User::find($id), 'lookup')->email;

Eloquent models, collections, arrays, objects, and primitives all render with type badges, child counts, and a memory size estimate. Keys matching password, token, secret, etc. are auto-redacted.

Timings

Profile blocks of code with start/stop marks.

Snip::start('elasticsearch');
$products = $repo->search($query);
Snip::timing('elasticsearch');

snip_time('build-payload');         // measured from request start

Each timing shows the elapsed duration in milliseconds plus where in the request lifecycle it ran, so you can see at a glance which block ate the budget.

Milestones

Confirm a code path executed without breaking the page.

snip_here('discount-applied');
snip_here('admin-fallback-path');

A non-fatal alternative to dd(). Useful for confirming a feature flag fired, a guard clause passed, or a fallback branch took over — anywhere you would have reached for dump() and a page reload.

DataLayer

Tees every window.dataLayer.push(...) call into a panel tab so GTM events are visible without opening the GTM debugger.

window.dataLayer.push({
    event: 'add_to_cart',
    ecommerce: { items: [...] },
});

The tab shows the event name, the full payload, and the order in which events were pushed during the page lifetime. Site-defined events are highlighted; framework noise (gtm.js, gtm.dom, gtm.load) is collapsed.

Disable with SNIP_DATALAYER=false.

Cache

Browse the active cache store without a separate tool.

Supported drivers:

Driver Lists keys Inspect value
redis Yes (SCAN with prefix) Yes (handles strings, lists, sets, hashes, zsets)
array Yes Yes
database Yes Yes
file Yes (hashed keys only) No
memcached No (driver not enumerable)

Click any key to fetch its value on demand — the panel never embeds cache contents in the HTML response. Useful for confirming a Cache::remember(...) actually wrote, or seeing what is currently under user:123:cart.

Disable with SNIP_CACHE=false.

Queue

Inspect jobs across the configured queue driver — failed, pending, scheduled, and (Horizon only) completed.

State Source
failed queue.failer — works on any driver
pending redis / database queues — jobs ready to run
scheduled redis / database queues — jobs delayed to a future time
completed Horizon completed_jobs table

Useful for verifying a job dispatch actually landed, checking why a notification has not gone out yet, or watching a queue drain during a deploy. Each list is paginated and capped (max_scan / per_page) so a 100k-job queue does not stall the request.

Disable with SNIP_QUEUE=false. Name your redis queues with SNIP_QUEUE_NAMES=high,default,low.

Configuration

Publish only when overriding defaults:

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

Most-used knobs:

Key Default Purpose
enabled env('SNIP_ENABLED', true) Master kill-switch.
display_mode 'on_capture' 'always' to show the pill on every gated response.
guard env('SNIP_GUARD') Auth guard for the gate. Null = framework default.
pending_redirects true Flash captures across redirect chains.
redact_keys [password, token, secret, …] Keys replaced with ***REDACTED***.
cache.enabled / queue.enabled / datalayer true Toggle individual tabs.
limits.* various Depth / array / string / per-kind hard caps.

See config/snip.php for the full reference with inline notes.

Security

  • Captures only reach users who pass the viewSnip gate.
  • Common credential keys auto-redacted; extend redact_keys for project-specific PII.
  • Injected responses are forced Cache-Control: private, no-store plus Vary: Cookie so shared caches (Varnish, CDN, response cache) cannot leak captures to other users.
  • Bundle file contains the renderer only — no captured data lives in JS.
  • The recording manager is scoped per request, so Octane and queue workers reset between requests.
  • The cache and queue lookup endpoints are gated by the same viewSnip ability — a guest hits 403, not the data.

License

MIT.

rudolfbruder/laravel-snip 适用场景与选型建议

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

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

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-09