documentCommand Line

docs/cli.md

Command Line

vendor/bin/sql-catalog [options] <path>...

Each path is a PHP file or a directory. Directories are searched recursively for *.php files, skipping vendor, node_modules, .git and build. Paths can also come from the configuration file; paths given on the command line replace them.

Without --output the report is written to standard output in the text format. With --output it is written into that directory in the json format, and the command prints the files it wrote.

$ vendor/bin/sql-catalog src/
src/UserRepository.php:23  SELECT  eea410b914be
  in App\UserRepository::findByStatus via pdo.prepare
  SELECT id FROM users WHERE status = :status
  resolved
  :status = 'active'|'banned'

Conditions are not evaluated; runtime reachability is not assessed.
1 statement(s), 1 fully resolved, 0 finding(s), 0 unreadable file(s).

Options

OptionDescription
-o, --output=DIRWrite the report into DIR instead of standard output.
-r, --reporter=NAMEtext, json or html. Default text on standard output, json with --output. See reports.
-c, --config=FILEConfiguration file. Default .catalog.yaml in the working directory, when it exists.
-e, --extension=NAMEDatabase API to recognise: pdo, mysqli, doctrine, laravel or wordpress. Default pdo,mysqli. See extensions.
--dialect=NAMESQL grammar of framework query builders: mysql, pgsql or sqlite. See Laravel.
--exclude=PATTERNSkip source files whose reported path matches the pattern or lies under it.
--root=DIRDirectory that reported paths are relative to. Default the working directory.
--fail-on=LEVELExit with 1 when a reported statement has a finding at LEVEL or above.
--list-extensionsList the extensions and exit.
--list-reportersList the reporters and exit.
-h, --helpShow the help and exit.

Options marked repeatable in --help can be given several times or as a comma-separated list, for example --kind insert,update. For other options the last value wins.

Help and the listings work without a configuration file and ignore it.

Filters

Filters select which statements are reported. They are applied after the analysis, so they do not change what a statement resolves to. Values of one filter are alternatives; different filters must all match.

OptionKeeps statements
--namespace=NSissued in a function or method under the namespace, ignoring case.
--method=NAMEissued in the function, written as name, Class::method or a pattern such as App\Repository\*::find*.
--path=PATTERNwritten in a file whose reported path matches the pattern or lies under it.
--kind=KINDof the kind: select, insert, update, delete, replace, merge, truncate, create, alter, drop, call, show, explain, transaction, other or unknown.
--table=NAMEnaming the table, ignoring case.
--sink=IDfound at the database call, such as pdo.prepare. unmatched selects calls whose receiver could not be identified.
--severity=LEVELwith a finding at LEVEL or above: info, low, medium or high.

Patterns use shell wildcards (*, ?, [...]) and are matched against paths relative to --root.

Exit codes

CodeMeaning
0Success.
1--fail-on is set and a reported statement reaches that severity.
2Invalid options or configuration.
3A source path cannot be read, the output cannot be written, or the extension or reporter named is unknown.

Files that fail to parse do not change the exit code. They are listed as unreadable in the report.

CI

Commit the JSON catalog and regenerate it in every pull request. The file is deterministic, so its diff is the change in the SQL the application issues:

vendor/bin/sql-catalog --output catalog/ src/
git diff --exit-code catalog/

To block SQL assembled from request input, fail on high-severity findings:

vendor/bin/sql-catalog --severity high --fail-on high src/

See reading a diff for what to look for.