MySQL DSN (Data Source Name)
debt(d5/e1/b3/t7)
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.
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.
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.
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.
Also Known As
TL;DR
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
Common Misconception
Why It Matters
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
// Hardcoded, no charset, credentials in DSN string
$pdo = new PDO('mysql:host=localhost;dbname=mydb;user=root;password=secret');
// 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']);