Skip to content

Character Sets and Collations

John James Jacoby edited this page Sep 23, 2026 · 6 revisions

Character sets and collations

The cached-connection behavior described below is available in LudicrousDB 5.3.1. It is not part of 5.3.0. Check your deployed version before relying on it in production.

LudicrousDB's default charset is utf8mb4, with utf8mb4_unicode_520_ci as its default collation. A charset names the character encoding; a collation controls comparisons and sorting. utf8mb4_unicode_520_ci is not a charset and should not be placed in DB_CHARSET or $wpdb->charset.

Which setting is used?

LudicrousDB starts with its defaults, applies DB_CHARSET and DB_COLLATE when defined, and then applies explicit constructor or db-config.php settings. The resulting $wpdb->charset and $wpdb->collate are the effective settings. The sample db-config.php explicitly sets both properties, so changing a constant alone may not change the final value in an installation using that sample.

Effective $wpdb->charset Connection behavior
utf8mb4 or another supported, non-empty charset Apply it with MySQLi and SET NAMES when a link is opened or its effective settings change. The calls are checked for failure; there is no separate session read-back query.
Empty string Leave the server's default charset in place. On a newly opened MySQLi link, or when the effective settings change to empty on a cached link, check the MySQLi client charset and read the server's client and connection charsets once. Reject an unsupported or unreadable session rather than silently trusting it.

An absent DB_CHARSET does not mean an empty charset: LudicrousDB starts from utf8mb4. An explicitly empty DB_CHARSET can produce an empty effective charset, unless a later setting such as the sample db-config.php overrides it.

When DB_CHARSET specifies a non-utf8mb4 charset and DB_COLLATE is absent, LudicrousDB leaves the collation empty instead of pairing the custom charset with its utf8mb4 fallback collation. Define a compatible collation only when you need one.

Likewise, when constructor arguments override the charset but omit the collation, LudicrousDB leaves the collation empty rather than inheriting one chosen for the previous charset.

When does the extra check run?

The session SELECT runs only for an empty effective charset when a MySQLi connection is first configured or a cached connection needs to adopt newly changed object settings. The latter can occur if code changes $wpdb->charset or $wpdb->collate after the connection was opened. A changed cached link may also need a liveness probe before it can be reconfigured safely, particularly if a result is still active. The check is per link within the current PHP request; its result is not shared through the WordPress object cache or retained for a fixed time across requests.

Ordinary reuse of a cached link with unchanged settings compares an in-memory record and sends no charset-validation query. LudicrousDB does not continually inspect the session after arbitrary SQL changes made behind its back. If custom code issues SET NAMES directly, it is responsible for keeping the client and server settings safe and consistent.

The check exists because an empty charset means LudicrousDB has not selected a known-safe encoding. The local MySQLi charset alone cannot show whether the server session was changed separately. Inspecting both sides lets LudicrousDB reject an unsupported initial session before using it for application queries; it is a one-time safeguard, not continuous monitoring. The observed charsets must each be supported, but need not match one another: the check does not choose a charset or promise identical client and connection settings.

How do I avoid the session read-back query?

Set a supported, non-empty effective charset. The supplied db-config.php already does this:

$wpdb->charset = 'utf8mb4';
$wpdb->collate = 'utf8mb4_unicode_520_ci';

You can also use matching WordPress configuration constants, provided a later db-config.php assignment does not override them:

define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', 'utf8mb4_unicode_520_ci' );

This avoids the read-back SELECT, not connection setup itself: a non-empty charset still requires MySQLi/SET NAMES commands when the link is configured. There is no separate switch to disable verification while continuing to use an empty effective charset. Test any charset or collation change against your actual MySQL/MariaDB versions and existing tables before deploying it.

Internal methods introduced by pull request #226

These are private implementation helpers, not extension points:

Method Purpose
is_connection_charset_current() Compare the cached link's recorded settings with the current object settings without a database round trip.
refresh_cached_connection_charset() Reconfigure a reused link only after those settings change, while accounting for busy results and connection recovery.
remember_connection_charset() Record the object settings associated with a MySQLi link. An explicit per-link override can differ from that record and persists until the object defaults change.
forget_connection_charset() Remove that record when a link closes or is replaced, so a later link cannot inherit stale state.
verify_default_connection_charset() Inspect client and server session charsets when an empty effective charset leaves the server default in control.

The record is an in-memory refresh trigger, not a read-back of the current server session. It cannot detect an out-of-band session change on every query without adding a database round trip to that hot path.

Clone this wiki locally