Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Soar Php Laravel Package

guanguans/soar-php

guanguans/soar-php is a PHP wrapper for Xiaomi's SOAR SQL optimizer and rewriter. It provides a simple, Laravel-friendly API to analyze, score, rewrite, and optimize SQL queries, with configurable options and support for multiple SQL dialects.

Deep Wiki
Context7

Getting Started

guanguans/soar-php is a thin, fluent PHP wrapper around Xiaomi's Go-based SOAR binary. The PHP package does not optimize anything itself — it shells out to the soar executable, so the binary is the real dependency.

Minimal steps:

composer require guanguans/soar-php
# install the SOAR binary separately (GitHub releases), then either put it on PATH
# or point the package at it via config/env
php artisan vendor:publish --provider="Guanguans\SoarPHP\SoarServiceProvider"  # Laravel
use Guanguans\SoarPHP\Soar;

$soar = Soar::make();

echo $soar->score('SELECT * FROM users WHERE id = 1');   // heuristic score
echo $soar->suggest('SELECT * FROM users WHERE id = 1'); // optimization advice

Where to look first:

  1. config/soar.php — binary path, default options, -test-dsn, log settings, OS-specific binary names.
  2. src/Soar.php — the fluent API surface (score, suggest, explain, rewrite, ast, fingerprint, html, md2html, pretty, exec).
  3. The package tests — they show exact option passing and output shape better than the README.

First real use case: wrap score() + suggest() in an Artisan command that takes a SQL string or file and prints a report. That gives immediate value with zero database connectivity required. Add explain()/rewrite() only once you have a safe -test-dsn configured.

Implementation Patterns

Fluent one-shot calls. Treat the Soar instance as a value object per analysis:

$result = Soar::make()
    ->setOptions(['-test-dsn' => $dsn, '-online-dsn' => $dsn])
    ->suggest($sql);

Create a fresh instance (or clone) per request/command rather than reusing a mutated singleton; SOAR options are positional and stale options leak between calls.

DSN from your existing connection. Don't hardcode credentials. In Laravel, derive the SOAR -test-dsn from config('database.connections.mysql'):

$dsn = sprintf('%s:%s@%s:%s/%s',
    $c['username'], $c['password'], $c['host'], $c['port'], $c['database']);

Point it at a read-only replica. SOAR uses it to run EXPLAIN, so the account needs SELECT/EXPLAIN only.

Machine-readable output for pipelines. For CI gates or dashboards, force JSON and parse:

$json = Soar::make()->setOutput('json')->suggest($sql);
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);

Gate a deployment on score() >= $threshold or on the presence of severity-tagged suggestions.

Batch analysis of .sql files / slow-query logs. Split on ; carefully (or use SOAR's own delimiter handling), loop, and aggregate by fingerprint(). Fingerprinting normalizes literals, so it is the right key for grouping “same query shape, different values” in a slow-query dashboard.

Rewrite as a review artifact, not auto-apply. rewrite() gives you candidate SQL. Store the original + rewrite + score delta, surface it in a PR comment or admin panel (html() / md2html() output is display-ready), and let a human approve. Never pipe rewrites straight into production migrations.

Raw escape hatch. When a SOAR flag isn't exposed by a named helper, use exec() with the raw argument array. Keep this centralized in one adapter class so an eventual SOAR upgrade only touches one file.

Caching. Analysis of the same SQL + same options is deterministic. Cache by sha1($sql . serialize($options)) for 24h; this matters when an admin UI re-renders the same recommendations repeatedly.

Gotchas and Tips

  • Binary missing or wrong architecture. The most common failure is soar: command not found or an incompatible binary (Linux amd64 vs Darwin arm64 vs Windows .exe). Set an absolute path in soar_binary, and verify with Soar::make()->version() in a health check.
  • DSN format is SOAR's, not Laravel's. -test-dsn expects user:password@host:port/database. A Laravel-style mysql://... URL or an empty DSN will cause explain/rewrite to fail or silently degrade to heuristic-only output.
  • Not every command needs a DSN; not every command works without one. score, suggest, fingerprint, ast, pretty are static-analysis. explain and parts of rewrite need live schema access. Design your feature so a missing DSN degrades gracefully.
  • ANSI color codes in output. SOAR may emit colored output when it thinks it's on a TTY. Pass --no-color (or strip escape sequences) before json_decode, or parsing will fail intermittently.
  • Shell quoting and argument length. SQL containing quotes, backticks, $, or newlines is dangerous if interpolated into a shell command. Prefer the package's stdin support, or at minimum pass arguments as an array so Symfony Process handles escaping. Very long SQL can exceed OS ARG_MAX — another reason to use stdin.
  • Output format drifts between SOAR versions. JSON keys and suggestion text change across releases. Pin the SOAR binary version in your Docker image and treat the JSON shape as a versioned contract with tests.
  • score() returns a string. Cast to int before comparisons; PHP's loose comparison can surprise you at "0" boundaries.
  • Process failures throw. Wrap calls in try/catch for ProcessFailedException/ProcessTimedOutException, set an explicit timeout, and log the command (minus credentials) for debugging.
  • Windows. The binary name needs .exe, and path separators in config are a frequent source of “works on my Mac” bugs. Normalize via DIRECTORY_SEPARATOR.
  • Security. SQL and DSNs frequently contain PII. Redact before logging, never accept a user-supplied -test-dsn, and don't expose raw exec() through an endpoint.
  • Extension point. SOAR supports a -config file for heuristics (blacklists, thresholds). Ship your own soar.toml alongside config/soar.php and pass -config in the options array when you need team-wide tuning.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums