Lightweight web database manager (MySQL / SQLite / SQL Server / Oracle), inspired by Adminer.
Version: v1.0.4 · Status: runnable prototype / near-MVP
Chinese: README.zh.md · Changes: CHANGELOG.md
- Multiple engines — MySQL · SQLite · SQL Server (Microsoft PHP extension, pure-PHP TDS, or Windows .NET CLI) · Oracle (same .NET CLI, driver
oracle_net). - Zero Composer runtime — plain PHP ≥ 5.5.12, drop-in deploy; document root = project root.
- SPA + all AJAX JSON — login, tree, grid, SQL, import/export never full-page postback; credentials stay in a server Session vault (not in every request body after login).
- Large-table friendly — load many rows once, VirtualGrid paints only the viewport; inline dirty cells, Ctrl+Enter submit, client column filters.
- Structure as a draft — reorder / add / drop columns in the UI, preview SQL, apply only changed columns (plus adds/drops).
- Real multi-connection — several browser tabs can hold different engines/hosts at once; connection id lives in the URL (
?c=). - Dump & import in-app — table export (SQL/CSV/XLSX/JSON) and database-level dump/import (SQL/CSV/TSV, gzip SQL) without leaving the page.
- Safer SQL console — multi-statement scripts split in the app; dangerous SQL secondary confirm; optional audit log lines under
storage/logs/. - Lightweight frontend — plain JS modules, no React / Vue / jQuery / npm build step for the app shell.
- Local / LAN ops and debugging when you want Adminer-class reach with a denser grid and multi-tab connections.
- Hosts where SQL Server PHP extensions are hard, but the database server is still reachable (use the pure-PHP SQL Server connector or the .NET CLI).
- Windows hosts that need Oracle without a PHP OCI extension (
oracle_netvia the same CLI). - Teams that need a small, self-contained web DB tool next to a PHP app — not a full BI suite.
Capability checklist (screens, APIs, config keys): see Feature catalog below.
- Login: engine / host / user / password (optional empty password via config) → Session with vault-encrypted credentials
- Saved profiles: connection list in
localStorage(optional remembered password is client obfuscation only, not encryption) - Drivers
- MySQL — PDO MySQL
- SQLite — PDO SQLite (path jailed under
sqlite_root) - SQL Server (extension) — Microsoft PHP SQL Server extension
- SQL Server (pure PHP) — connection implemented in pure PHP (no Microsoft extension; optional encryption)
- SQL Server (.NET CLI) — Windows helper
bin/SqlmngerMsCli.exe(.NET 4.8 SqlClient, Schannel TLS 1.2); resident singleton TCP daemon: PHP spawns it on demand, clients share one process, auto-exits after 60 s with no connection (mssql_net_idle_sec) - Oracle (.NET CLI) — same
SqlmngerMsCliprocess (engine=oracle+Oracle.ManagedDataAccess.dlland dependency DLLs beside the exe); login uses Service Name (host:port/service, default port 1521); full browse/SQL/grid CRUD via driveroracle_net
- Multi-tab connections: connection id in URL
?c=… - Database / table browse: filterable DB combo + left tree (context menu: data / structure / alter)
- Hash routing: restore active table, WHERE, sort, LIMIT, page, and mode (
m=struct/m=alter) - i18n: 中文 / English / 日本語 / 한국어 — dropdown on login and main title bar (preference in
localStorage)
- VirtualGrid: virtual scroll, dirty cells, submit / Ctrl+Enter, insert / multi-delete, WHERE + LIMIT + paging
- Edit: toolbar “Edit”, or Ctrl+click (Cmd+click) a cell to enter edit mode
- Cancel edit: no confirm dialog; reloads to discard dirty data
- Checked rows: highlight selected rows
- Client filters: column filter row (bottom Filter); closing it clears column filters
- Full-column search: status bar, next to row/selection stats
- Export (status bar): SQL / CSV / XLSX / JSON — open preview, download, or ZIP; scope page or all filtered
- View structure · Alter table draft (reorder, add above, drop on apply)
- Type / default comboboxes (type-to-filter + match highlight; free text)
- Defaults: quoted strings vs
NULL/ functions - Preview SQL before apply; only changed columns emit
ALTER(plus drops/adds) - Indexes (immediate write) · create table dialog
From the database overview page (export / import toolbar):
- Export (
api/db_export.php): SQL / CSV / TSV; open / save / ZIP; pick tables (structure / data); DROP+CREATE, AUTO_INCREMENT, triggers, routines, events; data as INSERT / INSERT IGNORE / REPLACE / none - Import (
api/db_import.php):.sql/.sql.gzupload (or JSON body); multi-statement execution; stop-on-error; size & statement caps
- Multi-statement scripts (app-layer split; batch results; stop on error)
- Dangerous SQL secondary confirm (DROP / TRUNCATE / unscoped DELETE·UPDATE, …) when
sql_require_danger_confirmis true - Result export: SQL / CSV / TSV / JSON — preview, download, ZIP
- Optional default row limit via
default_sql_limit(0= no auto LIMIT)
- Server admin views (privileges / processes / variables / status — best-effort per engine)
- Optional audit log (
log_operations→ JSON lines understorage/logs/) - All operations via AJAX + JSON
- PHP 5.5.12+ (modern PHP fine)
- Extensions as needed:
- MySQL:
pdo_mysql - SQLite:
pdo_sqlite - SQL Server (extension path): Microsoft SQL Server PHP extension
- SQL Server (pure PHP connector): only built-in PHP networking; openssl recommended if you enable encryption
- SQL Server / Oracle (.NET CLI): Windows + .NET Framework 4.8, with
bin/SqlmngerMsCli.exedeployed (Oracle also needsOracle.ManagedDataAccess.dll, dependency DLLs, and.exe.configbeside the exe)
- MySQL:
ZipArchivefor XLSX / multi-file ZIP exportgzdecodefor gzip SQL import (optional)
Point the web document root to the project root (where index.php lives), or:
php -S 127.0.0.1:8080 -t .Open the URL. After script updates use Ctrl+F5.
sqlmnger/
├── index.php # entry
├── .htaccess # Apache: UTF-8 + deny non-web paths/extensions
├── api/ # JSON APIs
│ └── tds/ # pure-PHP TDS + .NET CLI client
├── assets/
│ ├── css/ / js/ # app styles & modules
│ ├── favicon.*
│ └── xui/ # UI shell (runtime core.js; src not public)
├── bin/ # Windows .NET CLI runtime (exe / dll / config)
├── config/ # copy config.example.php → config.php (no secrets in git)
├── docs/
├── scripts/ # local tools (e.g. pack script)
├── storage/ # logs / sqlite (contents usually gitignored)
├── tmp/ # local temp (gitignored)
└── release/ # local release archives (*.7z, not committed)
v1.0.2+: former
public/tree is the project root; set the document root to the project root.
Build a deployable archive at release/phpsqlmgr_{version}.7z (local only; not uploaded to GitHub). Requires 7-Zip (7z on PATH or default install path).
node scripts/pack-release.js
node scripts/pack-release.js --version 1.0.4Archive root folder is phpsqlmgr/: index.php, api/, assets/ (without xui sources), bin/, config.example, empty storage placeholders; excludes tools/, tmp/, and local config.php.
.NET CLI sources live under tools/SqlmngerMsCli/ (lib/*.dll not in git). Build with slx SqlmngerMsCli rebuild to sync into bin/. See tools/SqlmngerMsCli/README.md.
cp config/config.example.php config/config.php| Key | Purpose |
|---|---|
app_key |
Vault key (≥32 chars); change in production |
debug |
Expose error detail on login fail |
allow_empty_password |
Allow empty DB password (local dev) |
session_ttl |
Cookie lifetime (default 7 days) |
enabled_drivers |
Enabled driver ids (mysql / sqlite / sqlsrv / mssql_tcp / mssql_net / oracle_net) |
mssql_net_idle_sec |
.NET CLI daemon idle-exit seconds with no client (default 60; applies to both mssql_net and oracle_net) |
sqlite_root |
SQLite path jail |
default_table_limit / default_sql_limit |
Default row limits (0 = unlimited / no auto LIMIT) |
max_fetch_rows / unlimited_soft_max |
Caps |
sql_require_danger_confirm |
Require confirm for dangerous SQL |
log_operations / log_path |
Audit JSON log |
| pure-PHP SQL Server encrypt | Encryption mode for the pure-PHP connector: auto / require / disable |
| pure-PHP SQL Server trust cert | Trust server certificate (self-signed LAN) |
import_max_bytes / import_max_statements |
Import caps (defaults apply if omitted) |
sql_exec_max_statements |
Max statements per SQL console submit |
Read via sqlmnger_cfg('key', $default).
Do not commit real secrets. Keep config.example.php as the public template.
| Code | Label |
|---|---|
zh |
中文 |
en |
English |
ja |
日本語 |
ko |
한국어 |
Stored as sqlmnger_lang in localStorage. UI strings live in assets/js/sqlmnger.i18n.js (some secondary screens still have partial hard-coded Chinese).
#v=1&k=t&db=mydb&t=mytable&l=10000
#v=1&k=t&db=mydb&t=mytable&m=struct
#v=1&k=t&db=mydb&t=mytable&m=alter
#v=1&k=sql&db=mydb
#v=1&k=server
Table tab titles: table name only when all open tables share one database; database.table when multiple DBs are open.
| Endpoint | Role |
|---|---|
auth_login / auth_logout / auth_me |
Session; multi-conn via c |
db_list / db_select / db_create / db_overview |
Databases |
db_export / db_import |
Database dump / SQL import |
table_list / table_data / table_structure / table_export |
Tables & row export |
table_row_save / table_row_insert / table_row_delete |
Row CRUD |
table_column (apply / preview) / table_index |
Structure DDL |
sql_exec |
Run SQL (single or batch) |
server_info / server_admin |
Server |
ping |
Health check |
- Change
app_key, setdebugtofalsein production - Prefer HTTPS and least-privilege DB accounts
- Set
allow_empty_passwordtofalseon public hosts - SQLite paths are jailed under
sqlite_root - Saved login passwords in the browser are obfuscated, not encrypted — avoid on shared machines
- Pure-PHP SQL Server connector: trusting the server certificate is convenient on LAN; use stricter certificate checks in production
- Keep the root
.htaccesson Apache: deniesbin/,tools/,config/,storage/,tmp/, source extensions, and direct_*.phpURLs - Keep audit logs and real
config.phpout of public VCS release/*.7zandtools/**/*.dll|exeare gitignored; ship runtimebin/with your deploy as needed
- App frontend is IIFE globals under
assets/js/(SqlmngerApp,SqlmngerTablePage,SqlmngerDbIO, …) — no bundler required for normal work - Shared chrome (layout / grid / dialogs) lives under
assets/xui/; usually leave it alone unless you are extending the shell - Release archive:
node scripts/pack-release.js→release/phpsqlmgr_*.7z - Agent/workspace rules: root
AGENTS.md(if present) - One-off scripts and backups go under
tmp/(gitignored); see.gitignore
Internal / project use unless otherwise stated.
