A streaming PHP parser for splitting multi-query SQL files into individual statements. Handles database-specific syntax like custom delimiters, dollar-quoted strings, and BEGIN...END blocks. The parser reads input in small chunks and yields statements one by one -- it never loads the entire file into memory, making it suitable for large SQL dumps.
- MySQL -- backtick identifiers,
DELIMITERcommand,#comments - PostgreSQL -- dollar-quoted strings (
$BODY$...$BODY$),E'...'escape strings - SQL Server --
[bracketed]identifiers,BEGIN...ENDblocks - SQLite -- all three identifier styles (
"double",`backtick`,[bracket]),BEGIN...ENDblocks for triggers
All parsers handle standard SQL comments (--, /* */), quoted strings, and semicolon delimiters.
composer require nextras/multi-query-parserRequires PHP 8.0+.
Parse a SQL file:
use Nextras\MultiQueryParser\MySqlMultiQueryParser;
$parser = new MySqlMultiQueryParser();
foreach ($parser->parseFile('migrations.sql') as $query) {
$connection->query($query);
}Parse a string:
$sql = "CREATE TABLE users (id INT); INSERT INTO users VALUES (1);";
foreach ($parser->parseString($sql) as $query) {
$connection->query($query);
}Parse from a file stream:
$stream = fopen('migrations.sql', 'r');
foreach ($parser->parseFileStream($stream) as $query) {
$connection->query($query);
}Available parsers: MySqlMultiQueryParser, PostgreSqlMultiQueryParser, SqlServerMultiQueryParser, SqliteMultiQueryParser.
Keep leading comments:
By default, comments are stripped and only query strings are yielded. To control what happens to
comments, pass a CommentStrategy to the parser constructor. The bundled PrependLeadingComments
strategy keeps the comments preceding a query as a prefix of that query -- useful when comments
carry meaningful annotations, e.g. so they remain visible in observability tools:
use Nextras\MultiQueryParser\Strategy\PrependLeadingComments;
$parser = new MySqlMultiQueryParser(new PrependLeadingComments());
$sql = "-- create the users table\nCREATE TABLE users (id INT);";
foreach ($parser->parseString($sql) as $query) {
echo $query; // "-- create the users table\nCREATE TABLE users (id INT)"
}All comment styles supported by the given dialect (--, /* */, and # for MySQL) that directly precede a query are preserved with their original formatting; only pure leading whitespace is stripped. A comment that sits between two queries is treated as preceding the following one. Comments not followed by any query (e.g. a trailing comment at the end of input) are dropped.
MIT. See full license.