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

时间:2016-05-20 12:32:30

标签: 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");

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

odbc_exec($conn, "SET NAMES 'UTF8'");
odbc_exec($conn, "SET client_encoding='UTF-8'");

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

------------------------------ edit ---------------- ---------------

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

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"])); 

    }

}

服务器日志说明如下:

--- 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"

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

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

6 个答案:

答案 0 :(得分:3)

您的数据库是ASCII扩展,而不是“Just ASCII”

线索在于:

  

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

%E1,或简称225,代表UTF8中的á。在扩展ASCII中它的ß。按住alt并输入225,你得到一个ß。

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

  

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

因为数据不是UTF8。

数据库中包含的是扩展的ASCII字符。常规ASCII是UTF8的子集,最多为128个字符,扩展不是。

如果您尝试过此操作,则无效;

iconv("ASCII", "UTF-8", $string);

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

odbc_exec($conn, "SET NAMES 'CP850'");
odbc_exec($conn, "SET client_encoding='CP850'");

如果你的原始断言是正确的,这可能会有效:

iconv("CP437", "UTF-8", $string);

或者这是我最初的预感,你的数据库是latin-1:

iconv("CP850", "UTF-8", $string);

IBM CP850具有ISO-8859-1(latin-1)所具有的所有可打印字符,仅仅是ISO-8859-1中的ß是223。

您可以在此页面的表格中看到ß的位置: https://en.wikipedia.org/wiki/Western_Latin_character_sets_%28computing%29

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

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

如果您的整个数据库使用相同的编码,这将有效。

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

Latin-1 / UTF-8 encoding php

// If it's not already UTF-8, convert to it
if (mb_detect_encoding($row["field"], 'utf-8', true) === false) {
    $row["field"] = mb_convert_encoding($row["field"], 'utf-8', 'iso-8859-1');
}

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

参考:

Force encode from US-ASCII to UTF-8 (iconv)

答案 1 :(得分:2)

尝试将Client_CSet=UTF-8添加到您的连接字符串。

答案 2 :(得分:2)

如果您知道服务器上的编码,请尝试将其添加到您的连接字符串

Client_CSet=UTF-8;Server_CSet=SERVER_ENCODING // for example WINDOWS-1251

答案 3 :(得分:1)

确保您的数据库字符集是utf8

试试这个
$connection_string = "Driver={Pervasive ODBC Client Interface};ServerName=127.0.0.1;dbq=@test;charset=UTF-8";

这可能对您有所帮助encoding

答案 4 :(得分:0)

1尝试

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

让我知道它是否有效..我试着帮忙。在一段时间之前有一个类似的问题:)

答案 5 :(得分:0)

试试这个..

<? 
# connect to a DSN "mydb" with a user and password "marin" 
$connect = odbc_connect("mydb", "marin", "marin");


# query the users table for name and surname
$query = "SELECT name, surname FROM users";



# perform the query
$result = odbc_exec($connect, $query);



# fetch the data from the database
while(odbc_fetch_row($result)){
  $name = odbc_result($result, 1);
  $surname = odbc_result($result, 2);
  print("$name $surname\n");
}



# close the connection
odbc_close($connect);
?>