Skip to content

Empty some values of mysqli_get_charset()#21361

Open
kamil-tekiela wants to merge 2 commits intophp:masterfrom
kamil-tekiela:mysqli_get_charset
Open

Empty some values of mysqli_get_charset()#21361
kamil-tekiela wants to merge 2 commits intophp:masterfrom
kamil-tekiela:mysqli_get_charset

Conversation

@kamil-tekiela
Copy link
Member

@kamil-tekiela kamil-tekiela commented Mar 6, 2026

state and dir were already constants. comment was undocumented and probably exposed unintentionally, as it doesn't report anything useful. number is emptied because this value probably should not be exposed to the users. It can be misleading. The value represents the ID that PHP associates with that character set based on the IDs of the default collations on the server (which can change so it can never be relied upon).

Before anyone asks about BC: this function never promised that the values wouldn't change. In the past, it has changed depending on which driver was used. I doubt anyone uses this useless function, but to keep the BC to minimum, the structure remains as documented in the PHP manual. Using the old values could even be considered a programming error as they haven't got a meaning outside of mysqlnd internals.

See #21338

Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the rationale makes sense. I'd add some comments for the properties you are adding that these are kept due to BC reasons.

@9EOR9
Copy link

9EOR9 commented Mar 7, 2026

I wouldn't skip/remove the charset->id check, since an error can indicate that a new character set/collation is not supported by mysqlnd. Instead we should obtain the character sets from information_schema.collations and check if the id is part of the list:

get_charset.php:

<?php

function get_charsets($link, $name)
{
    $sql = "SELECT id
        FROM information_schema.collations
        WHERE character_set_name = ? AND id IS NOT NULL";

    $stmt= $link->prepare($sql);
    $stmt->bind_param("s", $name);
    $stmt->execute();

    if ($result = $stmt->get_result())
    {
        $charsets = array_column($result->fetch_all(), 0);
    } else {
        $charsets= [];
    }
    $stmt->close();
    return $charsets;
}
?>

then in test:

require 'get_charset.php';
....

$charsetInfo = mysqli_get_charset($link);
$utf8mb3_charsets = get_charsets($link, "utf8mb3");

if (!empty($utf8mb3_charsets) &&
    !in_array($tmp->charsetnr, $utf8mb3_charsets)) {
    printf("[004] Charset %s not found: number %d not in [%s]\n",
        $charsetInfo->charset, $charsetInfo->number, implode(",", $utf8mb3_charsets));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants