Skip to content

Empty some values of mysqli_get_charset()#21361

Merged
kamil-tekiela merged 3 commits intophp:masterfrom
kamil-tekiela:mysqli_get_charset
Mar 7, 2026
Merged

Empty some values of mysqli_get_charset()#21361
kamil-tekiela merged 3 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));
}

@kamil-tekiela
Copy link
Member Author

since an error can indicate that a new character set/collation is not supported by mysqlnd

Right, but what impact would that have on mysqlnd? Wouldn't it be better to test the actual functionality that relies on it? If a new collation appears that's unsupported by mysqlnd then either the handshake or the set_charset() would fail. And for this we already have tests.

@kamil-tekiela kamil-tekiela merged commit eedbffe into php:master Mar 7, 2026
18 of 19 checks passed
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