如何在PHP中通过ODBC设置普及数据库的编码?

Tob*_*lis 5 php encoding pervasive

我开发了一个PHP脚本,它应该连接到一个普遍的数据库系统:

$connection_string = "Driver={Pervasive ODBC Client Interface};ServerName=127.0.0.1;dbq=@test"; 
$conn = odbc_connect($connection_string,"administrator","password");
Run Code Online (Sandbox Code Playgroud)

如果我执行查询,则返回的数据不是UTF8.mb_detect_encoding告诉我,编码是ASCII.我试图通过转换数据iconv,但它不起作用.所以我尝试了类似的东西来改变连接脚本后的编码:

odbc_exec($conn, "SET NAMES 'UTF8'");
odbc_exec($conn, "SET client_encoding='UTF-8'");
Run Code Online (Sandbox Code Playgroud)

但没有任何帮助!谁能帮我?谢谢.

------------------------------编辑------------------- ------------

这是完整的脚本,因为到目前为止没有任何工作:

class api {

    function doRequest($Url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $Url);
        curl_setopt($ch, CURLOPT_REFERER, "http://www.example.org/yay.htm");
        curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
        $output = curl_exec($ch);
        curl_close($ch);
    }

}

$connection_string = "Driver={Pervasive ODBC Client Interface};ServerName=127.0.0.1;dbq=@test;Client_CSet=UTF-8;Server_CSet=UTF-8"; 
$conn = odbc_connect($connection_string,"administrator","xxx");

if ($conn) {

    $sql = "SELECT field FROM table where primaryid = 102"; 
    $cols = odbc_exec($conn, $sql);

    while( $row = odbc_fetch_array($cols) ) { 

        $api = new api(); 
        // --- 1 ---
        $api->doRequest("http://example.de/api.html?value=" . @urlencode($row["field"])); 
        // --- 2 ---
        $api->doRequest("http://example.de/api.html?value=" . $row["field"]); 
        // --- 3 ---
        $api->doRequest("http://example.de/api.html?value=" . utf8_decode($row["field"])); 

    }

}
Run Code Online (Sandbox Code Playgroud)

服务器日志说明如下:

--- 1 --- [24/May/2016:14:05:07 +0200] "GET /api.html?value=Talstra%E1e+7++++++++++++++++++++++++++++++++++++++++++++++++ HTTP/1.1" 200 93 "http://www.example.org/yay.htm" "MozillaXYZ/1.0"
--- 2 --- [24/May/2016:11:31:10 +0200] "GET /api.html?value=Talstra\xe1e 7                                                 HTTP/1.1" 200 83 "http://www.example.org/yay.htm" "MozillaXYZ/1.0"
--- 3 --- [24/May/2016:14:05:07 +0200] "GET /api.html?value=Talstra?e 7                                                 HTTP/1.1" 200 93 "http://www.example.org/yay.htm" "MozillaXYZ/1.0"
Run Code Online (Sandbox Code Playgroud)

%E1代表á,但它应该是ß(德国字符)

\ xe1代表á,但它应该是ß(德国字符)

Pau*_*ley 4

您的数据库采用 ASCII 扩展格式,而不是“Just ASCII”

\n\n

线索就在这里:

\n\n
\n

%E1 代表\xc3\xa1,但它应该是\xc3\x9f(德语字符)

\n
\n\n

%E1,或者为了简单起见,225,代表 UTF8 中的 \xc3\xa1,. 在扩展 ASCII 中为 \xc3\x9f。按住 alt 键并输入 225,您将得到 \xc3\x9f。

\n\n

如果您的问题中的以下内容实际上是正确的:

\n\n
\n

如果我执行查询,返回的数据不是 UTF8。

\n
\n\n

因为数据不是 UTF8 格式的。

\n\n

数据库中的内容是扩展 ASCII 字符。常规 ASCII 是 UTF8 的子集,最多 128 个字符,扩展则不是。

\n\n

如果你尝试过这个,它不会起作用;

\n\n
iconv("ASCII", "UTF-8", $string);\n
Run Code Online (Sandbox Code Playgroud)\n\n

你可以先尝试这个,因为它是侵入性最小的,看起来mysql支持cp850,所以你可以在脚本的顶部尝试这个:

\n\n
odbc_exec($conn, "SET NAMES \'CP850\'");\nodbc_exec($conn, "SET client_encoding=\'CP850\'");\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您最初的断言是正确的,这可能会起作用:

\n\n
iconv("CP437", "UTF-8", $string);\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,我最初的预感是,您的数据库采用 latin-1 格式:

\n\n
iconv("CP850", "UTF-8", $string);\n
Run Code Online (Sandbox Code Playgroud)\n\n

IBM CP850 具有 ISO-8859-1(latin-1) 具有的所有可打印字符,只是 \xc3\x9f 在 ISO-8859-1 中位于 223。

\n\n

您可以在本页的表格中看到 \xc3\x9f 的位置:\n https://en.wikipedia.org/wiki/Western_Latin_character_sets_%28computing%29

\n\n

作为对现有代码的替代,在您的问题中,看看这是否有效:

\n\n
    $api->doRequest("http://example.de/api.html?value=" . $iconv("CP850", "UTF-8",$row["field"])); \n    // --- 2 ---\n    $api->doRequest("http://example.de/api.html?value=" . $iconv("CP850", "UTF-8",$row["field"])); \n    // --- 3 ---\n    $api->doRequest("http://example.de/api.html?value=" . $iconv("CP850", "UTF-8",$row["field"])); \n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您的整个数据库采用相同的编码,这将起作用。

\n\n

如果您的数据库没有始终遵循一种编码,则可能没有一个答案是完全正确的。如果是这种情况,您也可以尝试此处的答案,但使用不同的编码:

\n\n

Latin-1 / UTF-8 编码 php

\n\n
// If it\'s not already UTF-8, convert to it\nif (mb_detect_encoding($row["field"], \'utf-8\', true) === false) {\n    $row["field"] = mb_convert_encoding($row["field"], \'utf-8\', \'iso-8859-1\');\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我真正正确的答案是,如果可以的话,正确插入UTF8中的数据,这样就不会出现这样的问题。当然,这并不总是可能的。

\n\n

参考:

\n\n

强制从 US-ASCII 编码为 UTF-8 (iconv)

\n