← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

MySQL DSN (Data Source Name)

PHP PHP 5.1+ Beginner
debt(d5/e1/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep as the tool, and the pattern targets charset missing from the DSN or password embedded in it. Semgrep is a specialist SAST tool, not a default linter, so this lands at d5 rather than d3. Missing charset in particular is silent at runtime until encoding bugs surface, nudging slightly toward d5 rather than d7.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is explicit: add charset=utf8mb4 to the DSN string — a single-string edit. Removing a hardcoded password from the DSN is equally a one-line change. No cross-file refactor is required.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The DSN is constructed once per connection setup, typically in a single bootstrap or config file. The choice affects the one place where PDO is instantiated; the rest of the codebase is largely unaffected. It applies to web and CLI contexts but its footprint remains local.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field states that SET NAMES 'utf8mb4' is seen as equivalent to charset=utf8mb4 in the DSN. This contradicts the mental model of SQL commands as equivalent to configuration — developers familiar with MySQL's SET NAMES expect it to work identically, but encoding is actually set at the protocol level before any queries run. This is a documented gotcha that contradicts how similar configuration elsewhere appears to work, placing it at t7.

About DEBT scoring →

Also Known As

PDO DSN database connection string PHP mysql DSN format

TL;DR

The connection string passed to PDO specifying the database driver, host, port, database name, and charset.

Explanation

A MySQL DSN follows the format: mysql:host=hostname;port=3306;dbname=database;charset=utf8mb4. The charset parameter ensures the connection uses the correct encoding from the first packet. Omitting charset and using SET NAMES afterwards can cause a brief window where the wrong charset is active. Unix socket connections use unix_socket=/path/to/mysql.sock instead of host. The DSN does not include credentials — those are passed as separate constructor arguments.

Watch Out

Omitting charset from the DSN and using SET NAMES afterwards leaves a window where the wrong charset is active for the first query.

Common Misconception

SET NAMES 'utf8mb4' after connecting is equivalent to charset=utf8mb4 in the DSN. SET NAMES is a workaround — charset in the DSN sets encoding at the protocol level before any queries run.

Why It Matters

A malformed DSN causes a cryptic connection error. Missing charset causes encoding bugs. Using the wrong host/port in different environments causes environment-specific failures.

Common Mistakes

  • Omitting charset from the DSN and relying on SET NAMES — encoding mismatch before SET NAMES executes.
  • Hardcoding host/port in the DSN instead of reading from environment variables.
  • Including the password in the DSN string instead of the constructor's second and third arguments.

Avoid When

  • Never include credentials in the DSN string — pass them as the second and third PDO constructor arguments.
  • Do not hardcode DSN values — use environment variables for all connection parameters.

When To Use

  • Build the DSN from environment variables — never hardcode host, port, or database name.
  • Always include charset=utf8mb4 in the DSN string.

Code Examples

✗ Vulnerable
// Hardcoded, no charset, credentials in DSN string
$pdo = new PDO('mysql:host=localhost;dbname=mydb;user=root;password=secret');
✓ Fixed
// Build DSN from environment
$dsn = sprintf(
    'mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4',
    $_ENV['DB_HOST'],
    (int) ($_ENV['DB_PORT'] ?? 3306),
    $_ENV['DB_NAME']
);
$pdo = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASS']);

Added 31 Mar 2026
Views 40
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 1 ping F 2 pings S 2 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 1 ping T 2 pings W 0 pings T 0 pings F 0 pings S 3 pings S 0 pings M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Google 5 Scrapy 5 Unknown AI 3 Ahrefs 3 SEMrush 3 Meta AI 2 Claude 2 PetalBot 2 Perplexity 1 Sogou 1 Majestic 1
crawler 24 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Always include charset=utf8mb4 in the DSN — do not rely on SET NAMES after connection
📦 Applies To
PHP 5.1+ web cli
🔗 Prerequisites
PDO
🔍 Detection Hints
new PDO('mysql:...password=...') or charset not in DSN
Auto-detectable: ✓ Yes semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Low Context: Line
CWE-798


✓ schema.org compliant