Apache / PHP / FreeTDS中的特殊字符不一致,但命令行中没有PHP / FreeTDS

时间:2013-12-10 10:35:03

标签: php apache utf-8 freetds

我有两个相同的服务器(称为测试和生产),Linux Red Hat Enterprise Linux Server 6.2(Santiago),PHP版本5.4.2,Apache Apache 2.4.2,OpenSSL / 0.9.8s,freeTDS 0.92-dev(不是最好的事情,但我现在无法改变它,以及一个单独的Windows服务器与Microsoft SQL Server。

我有一个名为testfs1.php的PHP脚本,它从数据库中读取一个字符串,始终相同,并打印长度:没有别的。当然,最初的情况要复杂得多,但我还是努力简化。

数据库字段为NVARCHAR,所有组件都设置为使用UTF-8。

通常一切正常:脚本显示预期的字符串长度。但是每隔几个小时甚至几天,仅在生产服务器上(其中托管了几个使用频繁的应用程序),错误“激活”:Web服务器开始显示从数据库中提取的特殊字符错误。有时候,这个错误会在几分钟后自动“停用”;上次,它持续了几个小时,然后我跑了

service httpd restart

并停用了错误。

在错误处于活动状态的时间范围内,它是一致的:对页面testfs1.php的所有Web服务器请求都显示错误的结果;但是,当我手动运行时

php testfs1.php

在服务器的命令行上,即使它处于活动状态,也不会出现错误。

这是我日夜运行的Bash脚本,用于监控错误的激活:

#!/bin/bash

while : ; do
    echo -n `date +%H%M%S`
    wget https://www.mydomain.org/testfs1.php -o /dev/null
    echo -n "("
    cat testfs1.php
    echo -n ") "
    rm testfs1.php
    sleep 2
done

我用来重现问题的PHP脚本:

<?php
$Conn = mssql_connect( 'PROD', 'user', 'password' ) ;
mssql_select_db( "DBPROD", $Conn ) ;
$Ret = mssql_query( "SELECT lname FROM people WHERE people_key=123", $Conn ) ;
list( $s ) = mssql_fetch_row( $Ret ) ;
print strlen( $s ) ;

?>

这是freeTDS使用的locales.conf:

[default]
    date format = %b %e %Y %I:%M:%S:%z%p
    language = us_english
    charset = UTF-8

[en_US]
    date format = %b %e %Y %I:%M:%S:%z%p
    language = us_english
    charset = UTF-8

[es_ES]
    date format = %b %e %Y %I:%M:%S:%z%p
    language = us_english
    charset = UTF-8

[pt_BR]
    date format = %b %e %Y %I:%M:%S:%z%p
    language = us_english
    charset = UTF-8

[it_IT]
    date format = %b %e %Y %I:%M:%S:%z%p
    language = us_english
    charset = UTF-8

这个问题最令人费解的特点:

  1. 当从命令行使用PHP运行脚本时,从不会发生错误,只能从Apache
  2. 运行
  3. Bug在不同时刻“激活”,每隔几小时或几天激活一次,并自行“停用”或“服务httpd重启”
  4. 当在freeTDS使用的locales.conf中时,缺少行[default] / charset,错误是自发激活和自动停用(每隔几秒)
  5. 当同一服务器上的另一个应用程序使用gettext时,该错误会更频繁地自发激活和停用(每隔几秒)
  6. 一位同事暗示这可能是一个内存问题,考虑到重启Apache可以释放内存,并解释为什么它不会发生在流量最小的测试服务器上。我不相信。

    您能想象出可能的原因和解决方案吗?

1 个答案:

答案 0 :(得分:1)

坦率地说,我不知道是什么造成了这种不一致的工作。但我想建议你改变FreeTDS&amp; unixODBC到稳定版本。因为FreeTDS缺乏文档和支持。我一直在使用v0.82。它工作正常。

https://gitorious.org/freetds/mars-freetds/source/52e59affc0110c5ddd379ef1e45c4554123f27b5:README#L2

查找详细问题的另一种方法是在testfs1.php中使用PDO MsSQL。通过这种方式,如果本机mssql扩展对此不一致有任何影响,您可以更好地解决问题。