【问题标题】:PHP / SQL - Convert EBCDIC to ASCIIPHP / SQL - 将 EBCDIC 转换为 ASCII
【发布时间】:2013-05-02 13:44:20
【问题描述】:

我们有 PHP 服务器代码,针对我们的 iSeries 中端执行 SQL 语句。

这是 SQL 查询的简化版本

SELECT 'Regular' "sales_type", sum(sales_type1) "sales" FROM salesTable

查询执行得很好,问题是 当使用静态字段/值(例如 'SomeText' "Title" 并且在 PHP 中返回结果时,它们不是所需的格式

string(7) "م�����" 

连接到系统并检索结果

db2_connect ( '*LOCAL', 'user', 'pass' );
if (! $connection) {[error code]}
$stmt = db2_prepare ( $connection, $strSql );
if (! db2_execute ( $stmt ) ) { [error code ]
while ( $row = db2_fetch_array ( $stmt ) ) {
   var_dump($row[1]);
}

我们使用的是 PHP 版本 5.2.17

我们的 iSeries 是 V7R1M0

使用 PHP 或在 SQL 查询中转换服务器端的解决方案会很棒。

谢谢!


编辑

根据 bucks 的建议,我们已将用户配置文件 CCSID 更改为 37 而不是 65535

现在我们回到(下图)更近一点的地方......

string(7) "Ù…‡¤“™"

这可能是因为我们只更改了用户吗?系统、作业或表是否也需要更改?


编辑 2

这是phpinfo的输出

_COOKIE["ZDEDebuggerPresent"]   php,phtml,php3
_SERVER["ZendEnablerConfig"]    /www/zendserver/conf/fastcgi.conf
_SERVER["PHPRC"]    /usr/local/ZendSvr/etc/
_SERVER["PHP_FCGI_CHILDREN"]    40
_SERVER["PHP_FCGI_MAX_REQUESTS"]    0
_SERVER["CCSID"]    819
_SERVER["LANG"] C
_SERVER["INSTALLATION_UID"] 20101203131436121338
_SERVER["LDR_CNTRL"]    MAXDATA=0x40000000
_SERVER["LIBPATH"]  /usr/local/ZendSvr/lib
_SERVER["DB2NOEXITLIST"]    TRUE
_SERVER["ORACLE_HOME"]  .
_SERVER["ORA_NLS10"]    no value
_SERVER["ORA_NLS_PROFILE33"]    no value
_SERVER["FCGI_ROLE"]    RESPONDER
_SERVER["REDIRECT_UNIQUE_ID"]   UYKvWcCoAQIAAnZHWG8AABS@
_SERVER["REDIRECT_STATUS"]  200
_SERVER["UNIQUE_ID"]    UYKvWcCoAQIAAnZHWG8AABS@
_SERVER["QIBM_USE_DESCRIPTOR_STDIO"]    Y
_SERVER["HTTP_HOST"]    vmas400.vm.com:10090
_SERVER["HTTP_CONNECTION"]  keep-alive
_SERVER["HTTP_X_REQUESTED_WITH"]    XMLHttpRequest
_SERVER["HTTP_USER_AGENT"]  Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
_SERVER["CONTENT_TYPE"] application/x-www-form-urlencoded
_SERVER["HTTP_ACCEPT"]  */*
_SERVER["REFERER"]  http://vmas400.vm.com:10090ZendServer/Index/Index
_SERVER["HTTP_REFERER"] http://vmas400.vm.com:10090/ZendServer/Index/Index
_SERVER["REFERER_URL"]  http://vmas400.vm.com:10090/ZendServer/Index/Index
_SERVER["HTTP_ACCEPT_ENCODING"] gzip,deflate,sdch
_SERVER["HTTP_ACCEPT_LANGUAGE"] en-US,en;q=0.8
_SERVER["HTTP_ACCEPT_CHARSET"]  ISO-8859-1,utf-8;q=0.7,*;q=0.3
_SERVER["HTTP_COOKIE"]  ZENDSERVERSESSID=7asfv608qffhv556msem6evi66; CosmeticContest=16062; CompanyWithStoreDetail=16061; TYLYClassAnalysis=16068; OrderDetail=17220; RmsOrders=17221; DailyReceipts=16063; DailySales=17562; OnOrder=16064; OpenPurchaseOrders=17566; RegularPriceRankings=17568; ReviewStatistics=17570; SalesAndStock=17573; StocksByPeriod=17575; Top10BestSellers=17577; ReplenishmentAssortment=17269; RABS=17616; FreeFormatSku=16473; TYLYSalesAndOH=21294; SalesRecapByDate=16312; VendorAgendaSummary=23219; BasicStock=23474; InStock=16067; RegSalesAvgStockSummary=21270; TYLYSalesMDGMByStore=23822; VendorAgenda=23826; Header=16066; usc=adam; hudi[u]=d106b7a04c0d94b8a0e7624a017ead98324b57e8; hudi[i]=fec51923e58c84db4647d2b3e11fe03ec3f0c202; FreeFormat=16506; __utma=118969486.352613215.1355776933.1365626094.1367348033.12; __utmz=118969486.1355776933.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ZDEDebuggerPresent=php,phtml,php3
_SERVER["PATH"] /bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin
_SERVER["SERVER_SIGNATURE"] no value
_SERVER["SERVER_SOFTWARE"]  Apache
_SERVER["SERVER_NAME"]  vmas400.vm.com
_SERVER["SERVER_ADDR"]  192.168.1.2
_SERVER["SERVER_PORT"]  80
_SERVER["REMOTE_ADDR"]  172.16.129.193
_SERVER["DOCUMENT_ROOT"]    /www/zendserver/htdocs/prod
_SERVER["SERVER_ADMIN"] [no address given]
_SERVER["SCRIPT_FILENAME"]  /usr/local/zendsvr/gui/html/index.php
_SERVER["DOCUMENT_NAME"]    /usr/local/zendsvr/gui/html/index.php
_SERVER["REMOTE_PORT"]  14259
_SERVER["REDIRECT_QUERY_STRING"]    dojo.preventCache=1367519066445
_SERVER["REDIRECT_URL"] /ZendServer/Information/Phpinfo
_SERVER["GATEWAY_INTERFACE"]    CGI/1.1
_SERVER["SERVER_PROTOCOL"]  HTTP/1.1
_SERVER["REQUEST_METHOD"]   GET
_SERVER["QUERY_STRING"] dojo.preventCache=1367519066445
_SERVER["REQUEST_URI"]  /ZendServer/Information/Phpinfo?dojo.preventCache=1367519066445
_SERVER["SCRIPT_NAME"]  /ZendServer/index.php
_SERVER["DOCUMENT_URI"] /ZendServer/index.php
_SERVER["RULE_FILE"]    conf/httpd.conf
_SERVER["PHP_SELF"] /ZendServer/index.php
_SERVER["REQUEST_TIME"] 1367519066

编辑

解决方案

解决方案是将用户配置文件更改为使用 CCSID 37,并将服务器作业更改为使用 CCSID 37。我们将进行手动更改,以便在重新启动作业时它们不会恢复。

【问题讨论】:

    标签: php sql ascii ibm-midrange ebcdic


    【解决方案1】:

    如果 IBM 端配置正确,转换会自动发生。让 IBM 管理员检查系统值 QCCSID。如果设置为 65535,这就是不进行翻译的原因。 65535 表示系统上的所有数据都是二进制的,永远不应该翻译。 CCSID 有一个层次结构。它从系统级别的 QCCSID 开始,向下移动到用户配置文件,最后向下移动到单个表。这是为了处理使用多种语言的系统。

    系统在 65535 的主要原因是因为在部署当前中端机器的远祖时,只有一种语言;一个 EBCDIC,当引入多种语言时,默认语言设置为“不翻译”。

    EBCDIC 不再是单个字符集。每种语言都有一种编码。美国英语是 CCSID(37)。如果事实证明 CCSID 是问题所在,请让管理员使用正确的 CCSID 创建一个测试用户配置文件并尝试。

    编辑 1:我刚刚在我的机器上做了一个测试。

    编辑 2:向返回的列添加了文字。

    <?php
      //Establish connection to database
      $host = "midrange";
      $conn = db2_connect ($host, user, pass);
    ?>
    
    <table width="75%" border="1" cellspacing="1" cellpadding="1" bgcolor="#eeeeee">
    <tr>
      <td><b>Name</b></td>
      <td><b>Email</b></td>
      <td><b>3rd column</b></td>
    </tr>
    
    <?php
    $query = 'Select name, email, \'Markdown\' "THIRD" from table';
    
    //Execute query
    $queryexe = db2_exec($conn, $query) ;
    
    //Fetch results
    while(db2_fetch_row($queryexe)) {
     $name  = db2_result($queryexe, 'NAME');
     $email = db2_result($queryexe, 'EMAIL');
     $const = db2_result($queryexe, 'THIRD');
    
    //Put the results in an HTML table.
    print("<tr bgcolor=#ffffff>\n");
    print("<td>$name</td>\n");
    print("<td>$email</td>\n");
    print("<td>$const</td>\n");
    print("</tr>\n");
    }
    ?>
    </table>
    

    我所有的表都是 CCSID(37) IBM i 7.1。
    phpinfo() 报告 IBM_DB2 1.9.0, PHP 5.3.3 我注意到我启用了 iconv 支持并且我的服务器 CCSID 是 819 - US ASCII。

    编辑 3: 非常不完整的 phpinfo()

    ibm_db2
    IBM DB2, Cloudscape and Apache Derby support    enabled
    Module release  1.9.0
    Module revision     $Revision: 297218 $
    Binary data mode (ibm_db2.binmode)  DB2_BINARY
    DB2 instance name (ibm_db2.instance_name)   no value
    
    iconv
    iconv support   enabled
    iconv implementation    IBM iconv
    iconv library version   unknown
    
    Directive   Local Value Master Value
    iconv.input_encoding    ISO8859-1   ISO8859-1
    iconv.internal_encoding ISO8859-1   ISO8859-1
    iconv.output_encoding   ISO8859-1   ISO8859-1
    Environment
    Variable    Value
    ZendEnablerConfig   /www/zendsvr/conf/fastcgi.conf
    PHPRC   /usr/local/ZendSvr/etc/
    PHP_FCGI_CHILDREN   5
    PHP_FCGI_MAX_REQUESTS   0
    CCSID   819
    LANG    en_US
    INSTALLATION_UID    20101215125734236656
    LIBPATH     /usr/local/ZendSvr/lib
    DB2NOEXITLIST   TRUE
    
    PHP Variables
    Variable    Value
    _REQUEST["TJE"] no value
    _REQUEST["TE3"] no value
    _REQUEST["ZDEDebuggerPresent"]  php,phtml,php3
    _COOKIE["TJE"]  no value
    _COOKIE["TE3"]  no value
    _COOKIE["ZDEDebuggerPresent"]   php,phtml,php3
    _SERVER["ZendEnablerConfig"]    /www/zendsvr/conf/fastcgi.conf
    _SERVER["PHPRC"]    /usr/local/ZendSvr/etc/
    _SERVER["PHP_FCGI_CHILDREN"]    5
    _SERVER["PHP_FCGI_MAX_REQUESTS"]    0
    _SERVER["CCSID"]    819
    _SERVER["LANG"] en_US
    _SERVER["INSTALLATION_UID"] 20101215125734236656
    _SERVER["LIBPATH"]  /usr/local/ZendSvr/lib
    _SERVER["DB2NOEXITLIST"]    TRUE
    _SERVER["FCGI_ROLE"]    RESPONDER
    _SERVER["SCRIPT_URL"]   /hello.php
    _SERVER["QIBM_USE_DESCRIPTOR_STDIO"]    Y
    _SERVER["HTTP_USER_AGENT"]  Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0
    _SERVER["HTTP_ACCEPT"]  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    _SERVER["HTTP_ACCEPT_LANGUAGE"] en-US,en;q=0.5
    _SERVER["HTTP_ACCEPT_ENCODING"] gzip, deflate
    _SERVER["HTTP_DNT"] 1
    _SERVER["HTTP_CONNECTION"]  keep-alive
    _SERVER["HTTP_PRAGMA"]  no-cache
    _SERVER["HTTP_CACHE_CONTROL"]   no-cache
    _SERVER["PATH"] /bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin
    _SERVER["SERVER_SIGNATURE"] no value
    _SERVER["SERVER_SOFTWARE"]  Apache
    _SERVER["DOCUMENT_ROOT"]    /www/zendsvr/htdocs
    _SERVER["SERVER_ADMIN"] [no address given]
    _SERVER["SCRIPT_FILENAME"]  /www/zendsvr/htdocs/hello.php
    _SERVER["DOCUMENT_NAME"]    /www/zendsvr/htdocs/hello.php
    _SERVER["REMOTE_PORT"]  54747
    _SERVER["GATEWAY_INTERFACE"]    CGI/1.1
    _SERVER["SERVER_PROTOCOL"]  HTTP/1.1
    _SERVER["REQUEST_METHOD"]   GET
    _SERVER["QUERY_STRING"] no value
    _SERVER["REQUEST_URI"]  /hello.php
    _SERVER["SCRIPT_NAME"]  /hello.php
    _SERVER["DOCUMENT_URI"] /hello.php
    _SERVER["RULE_FILE"]    conf/httpd.conf
    _SERVER["PHP_SELF"] /hello.php
    _SERVER["REQUEST_TIME"] 1367514482
    

    编辑 4:如何制作服务器作业 CCSID(37)

    有几种方法可以让服务器作业运行美国英语。这是一个管理员决定,哪个对整个服务器操作的影响最小。我将仅美国英语的系统设置为通过 IPL 转到 QCCSID 37,但没有发现任何问题。

    1. CHGSYSVAL QCCSID 37 - 这会将整个服务器设置为美国英语。重启 Apache 服务器使其生效。
    2. CHGUSRPRF QTMHHTTP CCSID(37) - 这会将所有 HTTP 服务器作业设置为美国英语。重启 Apache 服务器使其生效。
    3. 重新配置 Apache 服务器。设置CgiConvMode EBCDICDefaultNetCCSID 819CGIJobCCSID 37重启Apache服务器生效。有关详细信息,请参阅CGI Data Conversions。这会将一台 Apache 服务器的作业设置为美国英语。
    4. CHGPF ... CCSID(37) - 这会将文件设置为美国英语。需要全部更改。

    这并非旨在包罗万象。更像是层次结构如何组合在一起的概要。

    【讨论】:

    • 嗯......我认为更近了一步。 (请参阅对 OP 的编辑)我们将用户配置文件更改为 37 而不是 *SYSVAL,现在我们返回 string(7) "Ù...‡¤“™" string(8) "Ô™'„–¦•" 这是一个更接近实际角色......有什么想法吗? - - 提前谢谢你!
    • 您希望看到什么价值观? SELECT 语句只有 2 列,但变量是 'string(7)' 和 'string(8)'。你能显示返回的十六进制值吗?
    • 我希望从 OP 中看到“常规”和“降价”。 或者至少是常见的英文字母:)...我在示例中的标题确实与我的实时代码不同,抱歉。我进行了编辑以显示正在使用的正确标题。响应短了一个奇怪的字符。返回的两个十六进制值是“d98587a4938199”和“d48199928496a695”,只是被重复了。删除重复以避免混淆。
    • 翻译需要两种编码。 DB2 端是 US EBCDIC (37),Web 端是 US ASCII (819)。查看显示 phpinfo() 输出的附加编辑。
    • 好的,验证一下,将返回两列,文字和销售额。文字以 EBCDIC 的形式返回,销售额是可读的 ASCII?或者问题是所有列都返回 EBCDIC 但只有当 SELECT 中有文字时?检查 Web 服务器作业 (WRKSBSJOB QHTTPSVR) 以查看它使用 CCSID 37。然后检查服务器上的 .php 文件 (WRKLNK) 以确保它是 819 或 1252。
    【解决方案2】:

    我发现了一种更好的方法...在您的 DSN 中使用 TRANSLATE or ForceTranslation keyword。例如:

    odbc:DRIVER={iSeries Access ODBC Driver};SYSTEM=as400.myserver.local;TRANSLATE=1;
    

    您不必更改任何文件、系统设置或在查询中使用 CAST。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多