aitradeinc/php-sql-parser
A PHP SQL parser library for analyzing SQL strings. Parse queries into structured data (AST/array) you can inspect, validate, rewrite, or use for tooling like linters, query builders, or migration helpers. Lightweight package for PHP applications.
Installation
composer require aitradeinc/php-sql-parser
Add the namespace to your project:
use Aitradeinc\SqlParser\Parser;
First Use Case Parse a simple SQL query to extract components:
$parser = new Parser();
$sql = "SELECT id, name FROM users WHERE id = 1";
$parsed = $parser->parse($sql);
// Output parsed structure
print_r($parsed);
Where to Look First
src/Parser.php for supported SQL features and parsing logic.SELECT, INSERT, JOIN).Parsing Queries for Dynamic Analysis Extract table/column names dynamically:
$parsed = $parser->parse("SELECT * FROM orders WHERE status = 'shipped'");
$tables = $parsed['tables']; // ['orders']
$columns = $parsed['columns']; // ['*']
Validation and Sanitization
Reject unsafe queries (e.g., containing DROP TABLE):
$sql = "SELECT * FROM users; DROP TABLE users;";
$parsed = $parser->parse($sql);
if (isset($parsed['statements'][1]['type']) && $parsed['statements'][1]['type'] === 'DROP') {
throw new \RuntimeException("Unsafe SQL detected!");
}
Generating SQL from Parsed Structures Rebuild queries programmatically:
$select = ['id', 'name'];
$from = ['users'];
$where = ['id = ?'];
$rebuiltSql = "SELECT " . implode(', ', $select) .
" FROM " . implode(', ', $from) .
" WHERE " . implode(' AND ', $where);
Integration with Query Builders Use parsed data to populate Laravel’s query builder:
$parsed = $parser->parse("SELECT id FROM users WHERE active = true");
$query = DB::table($parsed['tables'][0]);
foreach ($parsed['where'] as $condition) {
[$column, $operator, $value] = $condition;
$query->where($column, $operator, $value);
}
Handling Complex Queries Parse subqueries or joins:
$sql = "SELECT u.name FROM users u JOIN orders o ON u.id = o.user_id";
$parsed = $parser->parse($sql);
$joins = $parsed['joins']; // [['table' => 'orders', 'on' => 'u.id = o.user_id']]
$parsed = $parser->parse($request->input('sql'));
logger()->info('Executed SQL', ['parsed' => $parsed]);
doctrine/dbal: Use the parser alongside DBAL for advanced SQL analysis.Limited SQL Support
WITH RECURSIVE.OVER() clauses).ILIKE, MySQL’s ENGINE).False Positives in Parsing
WHERE name = 'O\'Reilly') may break parsing.Parser::parseWithStrings() if available, or pre-sanitize inputs.Performance Overhead
INSERT with 1000 rows) may be slow.No Standardized Output
$parsed = $parser->parse($sql);
$tables = $parsed['from'] ?? $parsed['tables'] ?? [];
No Active Maintenance
$parsed = $parser->parse("SELECT 1");
var_dump($parsed); // Check if keys like 'select', 'where' exist.
try {
$parser->parse("INVALID SQL");
} catch (\Exception $e) {
logger()->error("Parse error: " . $e->getMessage());
}
"").-- comment or /* multi-line */).select vs SELECT).Parser class to add options:
class CustomParser extends Parser {
public function parseWithOptions($sql, array $options) {
// Add logic for $options['ignore_case'], etc.
}
}
Add Custom SQL Types Extend the parser to recognize vendor-specific syntax:
// In a custom parser class:
protected function parseCustom($sql) {
if (strpos($sql, 'CUSTOM_KEYWORD') !== false) {
return ['type' => 'custom', 'sql' => $sql];
}
}
Plugin System Use composer autoloading to add parsers for specific SQL features:
// Register a plugin:
$parser->addPlugin(new CustomSqlPlugin());
Output Transformers Convert parsed data to other formats (e.g., JSON for APIs):
$json = json_encode([
'tables' => $parsed['tables'],
'columns' => $parsed['columns'],
]);
Integration with Laravel Events Listen to query events and parse SQL dynamically:
DB::listen(function ($query) {
$parser = new Parser();
$parsed = $parser->parse($query->sql);
// Log or analyze $parsed
});
How can I help you explore Laravel packages today?