A lightweight php class for formatting sql statements. Handles automatic indentation and syntax highlighting.

Overview

SqlFormatter

A lightweight php class for formatting sql statements.

It can automatically indent and add line breaks in addition to syntax highlighting.

History

I found myself having to debug auto-generated SQL statements all the time and wanted some way to easily output formatted HTML without having to include a huge library or copy and paste into online formatters.

I was originally planning to extract the formatting code from PhpMyAdmin, but that was 10,000+ lines of code and used global variables.

I saw that other people had the same problem and used Stack Overflow user losif's answer as a starting point. http://stackoverflow.com/a/3924147

Usage

The SqlFormatter class has a static method 'format' which takes a SQL string
as input and returns a formatted HTML block inside a pre tag.

Sample usage:

<?php
require_once('SqlFormatter.php');

$query = "SELECT count(*),`Column1`,`Testing`, `Testing Three` FROM `Table1`
    WHERE Column1 = 'testing' AND ( (`Column2` = `Column3` OR Column4 >= NOW()) )
    GROUP BY Column1 ORDER BY Column3 DESC LIMIT 5,10";

echo SqlFormatter::format($query);

Output:

Formatting Only

If you don't want syntax highlighting and only want the indentations and line breaks, pass in false as the second parameter.

This is useful for outputting to error logs or other non-html formats.

<?php
echo SqlFormatter::format($query, false);

Output:

Syntax Highlighting Only

There is a separate method 'highlight' that preserves all original whitespace and just adds syntax highlighting.

This is useful for sql that is already well formatted and just needs to be a little easier to read.

<?php
echo SqlFormatter::highlight($query);

Output:

Compress Query

The compress method removes all comments and compresses whitespace.

This is useful for outputting queries that can be copy pasted to the command line easily.

-- This is a comment
    SELECT
    /* This is another comment
    On more than one line */
    Id #This is one final comment
    as temp, DateCreated as Created FROM MyTable;
echo SqlFormatter::compress($query)

Output:

SELECT Id as temp, DateCreated as Created FROM MyTable;

Remove Comments

If you want to keep all original whitespace formatting and just remove comments, you can use the removeComments method instead of compress.

-- This is a comment
    SELECT
    /* This is another comment
    On more than one line */
    Id #This is one final comment
    as temp, DateCreated as Created FROM MyTable;
<?php
echo SqlFormatter::removeComments($query);

Output:


    SELECT
    
    Id 
    as temp, DateCreated as Created FROM MyTable;

Split SQL String into Queries

Another feature, which is unrelated to formatting, is the ability to break up a SQL string into multiple queries.

For Example:

DROP TABLE IF EXISTS MyTable;
CREATE TABLE MyTable ( id int );
INSERT INTO MyTable	(id)
	VALUES
	(1),(2),(3),(4);
SELECT * FROM MyTable;
<?php
$queries = SqlFormatter::splitQuery($sql);

Result:

  1. DROP TABLE IF EXISTS MyTable;
  2. CREATE TABLE MyTable ( id int );
  3. INSERT INTO MyTable (id) VALUES (1),(2),(3),(4);
  4. SELECT * FROM MyTable;

Why Not Regular Expressions?

Why not just use explode(';', $sql) or a regular expression?

The following example sql and others like it are impossible to split correctly using regular expressions, no matter how complex.

SELECT ";"; SELECT ";\"; a;";
SELECT ";
    abc";
SELECT a,b #comment;
FROM test;

SqlFormatter breaks the string into tokens instead of using regular expressions and will correctly produce:

  1. SELECT ";";
  2. SELECT ";\"; a;";
  3. SELECT "; abc";
  4. SELECT a,b #comment; FROM test;

Please note, the splitQuery method will still fail in the following cases:

  • The DELIMITER command can be used to change the delimiter from the default ';' to something else.
  • The CREATE PROCEDURE command has a ';' in the middle of it
  • The USE command is not terminated with a ';'
Comments
  • setup example cli as bin script; add color detection

    setup example cli as bin script; add color detection

    i found the example script is so useful it should be exported as binary via composer.

    also added color detection, so you can use the cli tool to format and when redirecting to file, it won't contain ANSI escapes, but if output to terminal, then it will be colored.

    opened by glensc 8
  • more compact WHERE conditions

    more compact WHERE conditions

    here's an idea for more compact where conditions.

    1. placing the condition keywords (AND, OR, etc) at the end of the lines makes it easier to focus on the participating columns rather than on statement construction.
    2. when IN is a simple list rather than a sub-query, having it compact saves a bunch of space. Even simple sub-queries like SELECTgroupFROMstuffWHERE type = 5 are better in-lined (though the heuristics for this could be fairly complex and probably add too much extra code).

    current

    current

    proposed

    proposed

    opened by leeoniya 4
  • sql-formatter fails

    sql-formatter fails

    I get the following exception when the sql below is being parsed. Exception: SQL Parse Error - Unable to tokenize string at character 24 -+ in ..../lib/vendor/jdorn/sql-formatter/lib/SqlFormatter.php at line 248

    SELECT * FROM crosstab('SELECT ......');
    
    opened by mvrhov 4
  • Token parser refactoring

    Token parser refactoring

    Hey there :)

    I've did some extensive profiling on the test case I've provided earlier this week and I've managed to refactor the biggest time consuming part of the token parser.

    Unfortunately it also introduces a small BC break, you can compare the files here: http://db.tt/Q2y2XXCh in terms of highlighting. It will recognize the non-escaped keywords as keywords not text. I think this could also be considered as bug fix rather that BC break.

    Besides this, I haven't noticed any side effects, the test now takes 1-2/10th of the previous run as for memory it's a increase of about 80k or so.

    Thanks and happy holidays!

    opened by dlsniper 4
  • Converted all self to static

    Converted all self to static

    This allows for extension of the library as any extending implementation won't be able to be used by the library.

    For additional details please see: doctrine/DoctrineBundle#139 and doctrine/DoctrineBundle#140

    Also, please tag this with 1.2 after merging so that we have a stable reference for the future commits.

    Maybe @stof can help you out with Composer and making it stable for it.

    Thank you very much.

    opened by dlsniper 4
  • upper case

    upper case

    Looks like this is an abandoned project. But if someone ever picks it up again...

    It would be wonderful if SQL key works could automatically be made uppercase... or perhaps optionally.

    -FT

    opened by ftrotter 3
  • Added namespacing

    Added namespacing

    Hi, I added namespacing to the formatter. This way it won't conflict with any classnames anyone is already using and it's pretty much the way libraries are organized nowadays I think.

    opened by RonRademaker 3
  • Prevent warnings in highlightToken

    Prevent warnings in highlightToken

    We use binary tokens and this will lead to a warning generated by htmlentities() which in turn means that the SF2 profile won't display any queries formatted with this bundle.

    If there's a better solution for this (seems pretty hacky), I am fine with it, too.

    opened by domnikl 3
  • PHP Notice: Undefined offset: -1

    PHP Notice: Undefined offset: -1

    I have the follow notice on the class. Maybe you have ad hoc a idea. Current was not easy to debug, how you start the $i and which values. I think is a problem, if the value $i is 0.

    Notice: Undefined offset: -1 in C:\xampp\htdocs\wp-plugins\debug-objects\inc\SqlFormatter\SqlFormatter.php on line 679

    Thanks for the project.

    opened by bueltge 3
  • Negative numbers have incorrect spaces

    Negative numbers have incorrect spaces

    Example queries:

    SELECT * FROM table WHERE column=-51 SELECT * FROM table WHERE column=-51.456 SELECT * FROM table WHERE column >= 50.123 AND column <= -51.456

    SqlFormatter::format() produces a space between the - and the number, e.g. "- 51".

    It seems MySQL and Postgres actually treat both "-51" and "- 51" the same. However, I would say the standard representation of negative numbers is without the space.

    opened by ladamson 3
  • added reserved keywords. Also added a method to remove newline after removing comments using removeComments method.

    added reserved keywords. Also added a method to remove newline after removing comments using removeComments method.

    added (

    'SQL_SMALL_RESULT' , 'GEMINI','GEMINI_SPIN_RETRIES','MASTER_LOG_POS','MASTER_PASSWORD','MASTER_PORT','MASTER_USER','MATCH',

    ,'MAX_CONNECTIONS_PER_HOUR','MAX_QUERIES_PER_HOUR','MAX_ROWS','MAX_UPDATES_PER_HOUR','MAX_USER_CONNECTIONS','RAIDO','RAID_CHUNKS','RAID_CHUNKSIZE','RAID_TYPE', 'SQL_AUTO_IS_NULL', 'SQL_BIG_RESULT', 'SQL_BIG_SELECTS', 'SQL_BIG_TABLES', 'SQL_BUFFER_RESULT',

    'SQL_CALC_FOUND_ROWS',
    'SQL_LOG_BIN',
    'SQL_LOG_OFF',
    'SQL_LOG_UPDATE',
    'SQL_LOW_PRIORITY_UPDATES',
    'SQL_MAX_JOIN_SIZE',
    
    'SQL_QUOTE_SHOW_CREATE',
    'SQL_SAFE_UPDATES',
    'SQL_SELECT_LIMIT',
    'SQL_SLAVE_SKIP_COUNTER',
    'SQL_SMALL_RESULT',
    'SQL_W
    

    'STRIPED','TRUE' 'XOR')

    opened by adityagoyal 3
  • Better formating for DECLARE, SET and WITH

    Better formating for DECLARE, SET and WITH

    Prevent this outcome: DECLARE @date_today DATE; SET @date_today = '2022-12-12'; DECLARE @date_weekago DATE; SET @date_weekago = '2022-12-05'; WITH duplicate AS (

    With this outcome: DECLARE @date_today DATE; SET @date_today = '2022-12-12'; DECLARE @date_weekago DATE; SET @date_weekago = '2022-12-05'; WITH duplicate AS (

    My DECLARE SET order is like this due dynamic content being added to the query.

    Maybe this doesn't suit all cases, such as multiple set at same line, but WITH and DECLARE at new line seems a must to me

    I also added @andig CROSS JOIN

    opened by buutqn 0
  • Formatting breaks when using '\'

    Formatting breaks when using '\'

    The following queries are formatted using SqlFormatter:format() method

    SELECT 
        path, 
        CHARINDEX(
            '\', path_sep) AS sep FROM dirs AS d
    
    SELECT 
        path, 
        '\' AS sep FROM dirs AS d
    
    opened by buutqn 0
  • Added Postgresql array operators.

    Added Postgresql array operators.

    Postgresql has support of an array type and there are two operators that break sql-formatter and it's depended php-reports. This pull-request adds support for <@ and >@ operators to sql-formatter.

    opened by daFool 0
  • A syntax error occurs in SQL formatting when sql code has '!=' operator

    A syntax error occurs in SQL formatting when sql code has '!=' operator

    When sql code has "!= "operator, formatting code gets wrong syntax formatting"! = ". There is an extra space between the "!" symbol and the "=" symbol

    for example:

    SELECT
      *
    FROM
      tableName
    WHERE
      dt = '2021-11-09'
      AND some != '111'
    

    i‘ll get it

    SELECT
      *
    FROM
      tableName
    WHERE
      dt = '2021-11-09'
      AND some ! = '111'
    

    Here's how I use it:

    import { format as sqlFormatter } from "sql-formatter";
    
    let newVal = "SELECT * FROM tableName WHERE dt='2021-06-09' AND some != '111'"
    sqlFormatter(newVal);
    

    [email protected] browser:Chrome@latest

    opened by xingorg1 0
  • Incorrect formatting of DELIMITER.

    Incorrect formatting of DELIMITER.

    1. Space is removed between DELIMITER and semicolon.

    If I execute

    \SqlFormatter::format('DELIMITER ;');
    

    Then I get DELIMITER;

    My expectation is that space will be preserved after DELIMITER.

    1. Error for forward slashes as DELIMITER.

    If I execute

    \SqlFormatter::format('DELIMITER //')
    

    then I get ErrorException "Uninitialized string offset: 1" line 217 in vendor/jdorn/sql-formatter/lib/SqlFormatter.php:

     if ($string[0] === '#' || (isset($string[1])&&($string[0]==='-'&&$string[1]==='-') || ($string[0]==='/'&&$string[1]==='*'))) {
    
    opened by vitalyspirin 0
Releases(v1.2.16)
  • v1.2.16(Nov 28, 2013)

    Summary of changes since last tagged release:

    • Added SqlFormatter::compress method for formatting queries on a single line. Useful for copy/pasting into the command line
    • Improved reserved word detection. For example, count is only a reserved word when followed by parentheses now
    • More reserved words recognized
    • Highlighting support for SQL variables and binary/hex numbers
    • Better formatting of LIMIT clauses
    • Increased PHPUnit code coverage
    • Performance improvements
    • Better negative number formatting
    Source code(tar.gz)
    Source code(zip)
PHP library to detect and manipulate indentation of strings and files

indentation PHP library to detect and manipulate the indentation of files and strings Installation composer require --dev colinodell/indentation Usage

Colin O'Dell 34 Nov 28, 2022
Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.

Motto: "Every business should have a detection script to detect mobile readers." About Mobile Detect is a lightweight PHP class for detecting mobile d

Şerban Ghiţă 10.2k Jan 4, 2023
highlight.php is a server-side syntax highlighter written in PHP that currently supports 185 languages

highlight.php is a server-side syntax highlighter written in PHP that currently supports 185 languages. It's a port of highlight.js by Ivan Sagalaev that makes full use of the language and style definitions of the original JavaScript project.

Geert Bergman 633 Dec 27, 2022
ATOMASTIC 14 Mar 12, 2022
A tiny PHP class-based program to analyze an input file and extract all of that words and detect how many times every word is repeated

A tiny PHP class-based program to analyze an input file and extract all of that words and detect how many times every word is repeated

Max Base 4 Feb 22, 2022
A PHP class which allows the decoding and encoding of a wider variety of characters compared to the standard htmlentities and html_entity_decode functions.

The ability to encode and decode a certain set of characters called 'Html Entities' has existed since PHP4. Amongst the vast number of functions built into PHP, there are 4 nearly identical functions that are used to encode and decode html entities; despite their similarities, however, 2 of them do provide additional capabilities not available to the others.

Gavin G Gordon (Markowski) 2 Nov 12, 2022
Text - Simple 1 Class Text Manipulation Library

Text - Simple 1 Class Text Manipulation Library Do you remember PHP's string functions? If not, just wrap you text with Text! It will save a minute on

Kazuyuki Hayashi 51 Nov 16, 2021
A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM.

A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM. s('string')->toTitleCase()->ensureRight('y') ==

Daniel St. Jules 2.5k Dec 28, 2022
Extensive, portable and performant handling of UTF-8 and grapheme clusters for PHP

Patchwork UTF-8 for PHP Patchwork UTF-8 gives PHP developpers extensive, portable and performant handling of UTF-8 and grapheme clusters. It provides

Nicolas Grekas 80 Sep 28, 2022
php-crossplane - Reliable and fast NGINX configuration file parser and builder

php-crossplane Reliable and fast NGINX configuration file parser and builder ℹ️ This is a PHP port of the Nginx Python crossplane package which can be

null 19 Jun 30, 2022
The Universal Device Detection library will parse any User Agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model.

DeviceDetector Code Status Description The Universal Device Detection library that parses User Agents and detects devices (desktop, tablet, mobile, tv

Matomo Analytics 2.4k Jan 5, 2023
Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way.

String Component The String component provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a un

Symfony 1.3k Dec 29, 2022
A fast PHP slug generator and transliteration library that converts non-ascii characters for use in URLs.

URLify for PHP A fast PHP slug generator and transliteration library, started as a PHP port of URLify.js from the Django project. Handles symbols from

Aband*nthecar 667 Dec 20, 2022
ColorJizz is a PHP library for manipulating and converting colors.

#Getting started: ColorJizz-PHP uses the PSR-0 standards for namespaces, so there should be no trouble using with frameworks like Symfony 2. ###Autolo

Mikeemoo 281 Nov 25, 2022
:clamp: HtmlMin: HTML Compressor and Minifier via PHP

??️ HtmlMin: HTML Compressor and Minifier for PHP Description HtmlMin is a fast and very easy to use PHP library that minifies given HTML5 source by r

Lars Moelleken 135 Dec 8, 2022
Tutorial for computer vision and machine learning in PHP 7/8 by opencv (installation + examples + documentation)

Examples detect face by cascade classifier detect face by pretrained caffe model res10_300x300_ssd by ddn module detect facemarks by LBF algorithm rec

null 409 Dec 25, 2022
"結巴"中文分詞:做最好的 PHP 中文分詞、中文斷詞組件。 / "Jieba" (Chinese for "to stutter") Chinese text segmentation: built to be the best PHP Chinese word segmentation module.

jieba-php "結巴"中文分詞:做最好的 PHP 中文分詞、中文斷詞組件,目前翻譯版本為 jieba-0.33 版本,未來再慢慢往上升級,效能也需要再改善,請有興趣的開發者一起加入開發!若想使用 Python 版本請前往 fxsjy/jieba 現在已經可以支援繁體中文!只要將字典切換為 bi

Fukuball Lin 1.2k Dec 31, 2022
Converts a string to a slug. Includes integrations for Symfony, Silex, Laravel, Zend Framework 2, Twig, Nette and Latte.

cocur/slugify Converts a string into a slug. Developed by Florian Eckerstorfer in Vienna, Europe with the help of many great contributors. Features Re

Cocur 2.8k Dec 22, 2022
Library for free use Google Translator. With attempts connecting on failure and array support.

GoogleTranslateForFree Packagist: https://packagist.org/packages/dejurin/php-google-translate-for-free Library for free use Google Translator. With at

Yurii De 122 Dec 23, 2022