【问题标题】:Unicode symbols become "??????????" at PHP side but data is NVARCHAR and SELECT shows correct dataUnicode 符号变成“????????????”在 PHP 端,但数据是 NVARCHAR 并且 SELECT 显示正确的数据
【发布时间】:2019-02-19 22:42:36
【问题描述】:

我有一个带有 SQL_Latin1_General_CP1_CI_AS 排序规则的数据库,我需要将其转换为 utf8_unicode_ci 排序规则。改变表格不是一种选择。 MSSQL 返回数据如下:

[FirstName] => ??????????

但是像这样的真实数据:

[FirstName] => مریم

我已经尝试了这些方法:

$utf8[] = utf8_encode($saleagent['FirstName']);
$utf8[] = iconv('ISO-8859-1', 'UTF-8',$saleagent['FirstName']);
$utf8[] = mb_convert_encoding($saleagent['FirstName'], 'UTF-8', 'ISO-8859-1');

输出是:

Array
(
    [0] => ??????????
    [1] => ??????????
    [2] => ??????????
)

有没有办法将现有数据转换为utf8_unicode_ci?

编辑


根据this answer,我改了代码:

在 SQL 中:

CAST(p.FirstName AS VARBINARY(MAX)) as FirstName,

在 PHP 中我写了这个函数来修复编码:

public function fixEncoding($string)
{
    $original = $string;
    $string = trim($string);
    // Detect the input string encoding.
    $encoding = mb_detect_encoding($string, mb_detect_order(), false);

    if ($encoding == 'UTF-8' || $encoding == false) {
        $hex = bin2hex($string);

        $str = "";
        for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
            $str .= chr(hexdec($hex[$i] . $hex[$i + 1]));
        }
        $string = iconv('UCS-2LE', 'UTF-8', $str);
        return $string;

    } elseif ($encoding == 'ASCII') {
        $string = $original;
        return $string;
    }

    return $string;
}

让我解释一下情况。 我在mssql 数据库中遇到了 3 种类型的字符串:

  1. 英文字符或数字等字符串:xyz 32 -
  2. 类似波斯字符的字符串:مریم دختر خوبی است
  3. 上述两个字符串:مریم دختر خوبی است - Maryam is a good girl.

发生的情况是,12 中的代码转换成功。但是,数字 3 在尝试将其转换为 iconv 时返回错误,并引发以下错误:

iconv():在输入字符串中检测到不完整的多字节字符

在这一行:

$string = iconv('UCS-2LE', 'UTF-8', $str);

你有任何解决方案来处理这三种情况吗?

【问题讨论】:

标签: php sql-server collation iconv


【解决方案1】:

可能的原因:

  • 表/列未声明为 UTF-8
  • 客户端中的字节未编码UTF-8

【讨论】:

    【解决方案2】:

    解决方案:

    你可以试试这个:

    • 用 UTF-8 编码你的 html 和 php 文件(这一步我通常使用 Notepad++)。
    • 使用CONVERT(varbinary(max), UNICODECOLUMN); 从 MS SQL Server 中选择值
    • $value = iconv('UTF-16LE', 'UTF-8', $unicodetext);转换PHP部分中的值

    您可以将您的功能更改为:

    <?php
    ...
    public function fixEncoding($string) {
        return iconv('UTF-16LE', 'UTF-8', $string);
    }
    ...
    ?>
    

    示例:

    <html>
        <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta charset="utf-8">
        </head>
        <body>
        <?php
        # Connection
        $server   = "server\instance,port";
        $user     = "user";
        $password = "password";
        $database = "database";
        $cinfo = array(
            "Database" => $database,
            "UID" => $user,
            "PWD" => $password
        );
        $conn = sqlsrv_connect($server, $cinfo);
        if ($conn === false)
        {
            echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
            exit;
        }
    
        # Statement
        $sql = "
            SELECT CONVERT(varbinary(max), [NVARCHARTEXT]) AS [NVARCHARTEXT] 
            FROM [dbo].UnicodeText
        ";
        $stmt = sqlsrv_query($conn, $sql);
        if ($stmt === false) {
            echo "Error (sqlsrv_prepare): ".print_r(sqlsrv_errors(), true);
            exit;
        }
        while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
            $value = $row["NVARCHARTEXT"];
            $value = iconv('UTF-16LE', 'UTF-8', $value);
            echo $value.'</br>';
        }
    
        # End
        sqlsrv_free_stmt($stmt);
        sqlsrv_close($conn);
        ?>
        </body>
    </html>
    

    注意事项:

    示例使用PHP Driver for SQL Server、SQL Server 2012、带有nvarchar 列的表。

    【讨论】:

    • 在某些情况下它不起作用,我有这样的字符串:????? ???????? ????? ?????? ???? 5?2
    • @SiamakA.Motlagh 抱歉耽搁了。你能描述一下你的情况吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2023-04-05
    • 2019-11-22
    • 2011-03-23
    相关资源
    最近更新 更多